MongoDB > Can I upsertMany using instance data in the query - javascript

I'm currently attempting to synchronise data from an external source, into a Mongo database. The data comes in, as an array, and I'd like to BULK insert or update ("upsert") the data, depending on whether a record with a matching customid already exists.
var data = [{
customid: '123',
name: 'Bob',
occupation: 'Builder'
}]
db.foobar.insertMany(data)
Insert is fine, but now (on subsequent synchronisations), I would like to insert/update the following (sample) data, not knowing if the customid exists... is there any way to do this as a bulk operation? e.g.
var newdata = [{
customid: '123',
name: 'Bob',
occupation: 'Nightclub Bouncer'
}]
db.foobar.updateMany({ customid: $instance.customid }, newdata, { upsert: true })
... or is the only way, to manually iterate over the records and run an update(..)?

I've found a compromise, using bulkWrite and multiple updateOne statements. If anyone has a better solution, please don't hesitate to post it.
https://stackoverflow.com/a/47832754/782034

Related

json-server : how to do complex queries

I have a set of users each with a team id.
I have a set of records which are 'owned' by a user.
e.g.
users: [
{ id: 1, teamId: 1234 },
...
],
records: [
{ id: 1, usersId: 1 },
....
]
Can I issue an API call to json-server that either
gets all records owned by users with a specific teamid?
/records?users.teamId=1234
According to the API guide I've found, this should work but doesn't. Adding _expand=users onto the query does seem to show the tables are linked.
alternatively gets all records if I provide a list of userids to filter on?
/records?usersId=[1,2,3,4]
Is there any complete documentation on what you can do on the json-server API?

How to update a field of an object inside an array inside an object in MongoDB using Node.js?

I am developing a Node.js application using MongoDB as a database. I have created a collection called users and the structure of it is as below:
{
username: 'Alex',
email: 'alex#test.com',
password: '123456',
cart: {
items: [
{
productId: 574894734,
quantity: 1,
}
],
},
}
When the user clicks on the "add to cart" button, I want to check if the cart already contains the product. If it contains the product I want to increase its quantity otherwise I want to add it.
I've tried a lot of solutions on StackOverflow but I couldn't solve the problem.
I get duplicated items in the cart object.
Help me.

Find Value in Meteor Mongo

I am new to web programming and have recently been playing around with Meteor and MongoDB.
I have a form which sends data to mongo and using the query below have retrieved the most recently entered value:
database.findOne({}, {sort: {'timeStamp' : -1}, limit:1})
Which is cool however, I only want the value of a specific variable not the entire entry so I can use that variable with calculations elsewhere.
Does anyone have an pro tips? Should I use distinct()?
Thanks!
If you are looking to retrieve a field out of the returned document, you can specify as much using the fields option:
database.findOne({}, {sort: {'timeStamp' : -1}, limit:1, fields: {'myField': 1, _id: 0})
That will retrieve an object in format like this:
{'myField': 'value of myField'}
So if you want to interact directly with that you can access it like so:
var myVar = database.findOne({}, {sort: {'timeStamp' : -1}, limit:1, fields: {'myField': 1, _id: 0}).myField
As a more concrete example, I have a user database with username, name, _id, etc., and if I just want to store a user's name in another variable, I can do so like this:
> a = Meteor.users.findOne({}, {fields: {name: 1, _id: 0}}).name;
> a
<- "Bob" // returned "Bob"
Note that if you want to pull the data for a specific ID or other selector, you'll need to fill that in in the selector:
database.findOne({_id: "myId"}, ...)
See the Meteor Mongo.Collection.find documentation for more information.

Using mongojs and node.js, how to find documents using multiple attributes as criteria

I am trying to use the find method to return documents that meet multiple criteria like so:
db.issues.find({ 'title.name': name, 'title.year': year, 'title.publisher': publisher }, function(err, issues) { ...
I get an empty array back as a result.
If I try the same query directly in the mongodb console, I get the results back as expected.
In mongojs, I am able to retrieve results if I only supply one attribute, like so:
db.issues.find({ 'title.name': name }, function(err, issues) { ...
So, how do I perform a search using multiple attributes? Do I need to use a different method?
UPDATED 2/2/2014 7:56
The issue schema is as follows:
{
title: { name: 'Some title name', year: 1999, publisher: 'Some publisher' },
number: "122",
variant: null,
print: "1",
year: "1999",
certification: { type: "Some certification", grade: 10 },
url: "http://www.someurl.com",
sales: []
}
There is no difference in how mongojs handles queries as it's intention is to mimic ( somewhat ) the behavior of the mongo shell.
Are you sure your criteria actually returns something? As it stands you possibly have an issue there. If you still cannot diagnose this, post up the result you expect to get and some of your schema as an edit. Don't forget to check your var's that numbers aren't strings and vice versa.

fetchRelated not fetching related

Been trying to get this up and running for a while now.
Basically i have a rest api as backend that returns json, all fine.
The problem i have is with backbone-relational. I'm sure i've just got something
wrong but i've been searching the nets for a while and couldn't find anything to help.
I'm trying to get a has many relationship between the model "Profession" and "Weapon".
Here's my code for that:
Profession = Backbone.RelationalModel.extend({
urlRoot: '../api/professions',
relations: [{
type: Backbone.HasMany,
key: 'weapons',
relatedModel: 'Weapon',
collectionType: 'Weapons',
reverseRelation: {
key: 'profession',
includeInJSON: 'id',
keySource: 'profession_id'
}
}]
});
Weapon = Backbone.RelationalModel.extend({
urlRoot: '../api/weapons'
});
Weapons = Backbone.Collection.extend({
model: Weapon,
url: function(models){
return '../api/weapons';
}
});
And a call to those api endpoints returns:
{name: "Profession1", id: 1}
[{name: "Weapon1", profession_id: 1}, {name: "Weapon2", profession_id: 1}]
So, if i understand correctly a profession.fetchRelated('weapons') should send an httprequest to the url for the weapons collection and pull the object which have a profession_id of 1. But nothing happens when i run profession.fetchRelated('weapons')
So, if i understand correctly a profession.fetchRelated('weapons') should send an httprequest to the url for the weapons collection and pull the object which have a profession_id of 1. But nothing happens when i run profession.fetchRelated('weapons')
This is not how I understand Backbone-relational to work - with the caveat that I'm working with an older version, and have not yet investigated the latest versions.
From my understanding, Backbone-relational wants data that looks different from your API responses.
I think that Backbone-relational wants references to nested models in the parent model response, either fully nested:
{
name: "Profession1",
id: 1,
weapons: [
{name: "Weapon1", profession_id: 1},
{name: "Weapon2", profession_id: 1}
]
}
In which case, it will fully populate the nested models.
Or, as references:
{
name: "Profession1",
id: 1,
weapons: ['weapon1','weapon2']
}
In which case Backbone-relational will stash the related keys internally, but present an empty collection. You would then use fetchRelated to fetch the full data for the related models:
assassin.fetchRelated('weapons')
Which make a request for weapons with id 'weapon1' and 'weapon2', either as individual requests, or if your API accepts a set request, a single request, expecting a response something like:
{id: 'weapon1', name: "Weapon1", profession_id: 1}
I don't, off the top of my head, know if there's a quick, built-in way to work with your API responses, other then to write a custom function.
To add to what Edward wrote, here's how you can get fetchRelated to work. First, as Edward claimed, fetchRelated will return nothing if your API already nests the data in the JSON response. So, if in Django-Tastypie you have your resource set up to use full=True:
movies = fields.ToManyField('movie.api.MovieResource', 'user', full=True)
then something like,
myuser.fetchRelated("movies")
will return nothing because the related data will already be included in the JSON response. But where fetch related is particularly useful is when you are attempting to do some lazy loading. So, if you have full=False in your Django-Tastypie field, and your JSON response only includes the id's and resource URI to that entry, you can use fetchRelated to actually populate that data.
myuser = new User({id: 1})
myuser.fetch()
myuser.fetchRelated("movies")
And now you have access to the related movies collection. If you're also using the Tastypie-Backbone plugin, you don't need to worry about constructing a special URL return statement in the Collection. It does it all for you using the tastypie select syntax of /2;3;7

Categories