How to update multiple users with different value in mongoose? - mongodb

I have two users. test1 and test2. I need to update language for that users in single query.
Now i am looping them
db.collection.update({name : test1}, {lang: node})
db.collection.update({name : test2}, {lang: php})
But i don't want that, how can i do that in single query?
is there any way like
db.collection.update({[{name: test1}, {lang: node}], [{name : test2}, {lang: php}]}, {multi:true})
or
if (name: test1){update lang: node} elseif (name: test2){update lang : php}
sample document
{
_id: 231123,
name : test1,
lang : java
}

Try the Bulk API: https://docs.mongodb.com/v3.2/reference/method/Bulk/
Normal update API doesn't provide what you want since the query for the update operations are not the same. Bulk is the only API that comes to mind for your use case.

Related

Need Help on Mongo DB query

There is an existing person collection in the system which is like:
{
"_id" : ObjectId("536378bcc9ecd7046700001f"),
"engagements":{
"5407357013875b9727000111" : {
"role" : "ADMINISTRATOR",
},
"5407357013875b9727000222" : {
"role" : "DEVELOPER",
}
}
}
So that multiple user objects can have the same engagement with a specific role, I need to fire a query in this hierarchy where I can get all the persons which have a specific engagement in the engagements property of person collection.
I want to get all the persons which have
5407357013875b9727000222 in the engagements.
I know $in operator could be used but the problem is that I need to compare the keys of the sub Json engagements.
I think it's as simple as this:
db.users.find({'engagements.5407357013875b9727000222': {$exists: true}})
If you want to match against multiple engagement ids, then you'll have to use $or. Sorry, no $in for you here.
Note, however, that you need to restructure your data, as this one can't be indexed to help this concrete query. Here I assume you care about performance and this query is used often enough to have impact on the database.

Search backward on MongoDb

I have 2 collection.
Collection "users"
{
"_id" : ObjectId("54b00098e0fdb6634b1f54e6"),
"state" : "active",
"backends" : [
DBRef("backends", ObjectId("54b001ebe0fd853df1c93419")),
DBRef("backends", ObjectId("54b00284e0fd853df1c9341b"))
]
}
Collection "backends"
{
"_id" : ObjectId("54b001ebe0fd853df1c93419"),
"state" : "running"
}
I want to get a list of backend of a user where the backend's state is "running".
How can mongodb do this like join two table?
Is it any method to search backward from backend or have function the filter?
I can search like this
db.users.find({"backends.$id" : "distring"})
But what if I want to search the state inside backend object? like.
db.users.find({"backends.$state" : "running"})
But ofcoure it is not working.
MongoDB doesn't support joins so you need to do this in two steps. In the shell:
var ids = db.backends.find({state: 'running'}, {_id: 1}).map(function(backend) {
return backend._id;
});
var users = db.users.find({'backends.$id': {$in: ids}}).toArray();
On a side note, you're probably better off using a plain ObjectId instead of a DBRef for the backends array elements unless the ids in that array can actually refer to docs in multiple collections.

mongodb query in 2 collections

I have define 2 reconds in 2 collections separately in one mongo db like this
order:
{
"_id" : ObjectId("53142f58c781abdd1d836fcd"),
"number" : "order1",
"user" : ObjectId("53159bd7d941aba0621073e3")
}
user
{
"_id" : ObjectId("53159bd7d941aba0621073e3"),
"name" : "user1",
"gender" : "male"
}
when I use this command in console, it can not execute
db.orders.find({user: db.user['_id']}) or db.orders.find({user: user['_id']}),
is there anything wrong? Thanks!
Another way is to:
> var user = db.users.findOne({name: 'user1'});
> db.orders.find({user: user._id});
This way can be a bit more flexible especially if you want to return orders for multiple users etc.
Taking your comment:
Thanks, but actually, I want to search all the orders of all users, not only one user. So what would I do? Thanks
db.users.find().forEach(function(doc){
printJson(db.orders.find({user: doc._id}));
});
I think you want:
db.order.find({'user':db.users.findOne({'name':'user1'})._id})
All you need to do is to make a query and check the output before inserting it into the query.
i.e. check that:
db.users.findOne({'name':'user1'})._id
has the output:
ObjectId("53159bd7d941aba0621073e3")
If you want to run larger queries, you're going to have to change your structure. Remember that Mongodb doesn't do joins so you'll need to do create a user document that looks like this:
user
{
"name":"user1",
"gender":"male",
"orders":[
{
'number':'order1'
}
]
}
You can then update this using:
db.user.update({'_id':ObjectId('blah')}, {'orders':{$push:{'number':'order2'}})
This will then start you with order tracking.
Mongo will be able to find using the following:
db.user.find({'orders.numbers':'order2'})
returning the full user record
Maybe you can help this solution:
use orders
db.getCollection('order').find({},{'_id':1})
db.getCollection('user').find({},{'_id':1})

Reference an _id in a Subdocument in another Collection Mongodb

I am developing an application with mongodb and nodejs
I should also mention that I am new to both so please help me through this question
my database has a collection categories and then in each category I am storing products in subdocument
just like below :
{
_id : ObjectId(),
name: String,
type: String,
products : [{
_id : ObjectId(),
name : String,
description : String,
price : String
}]
});
When it comes to store the orders in database the orders collection will be like this:
{
receiver : String,
status : String,
subOrders : [
{
products :[{
productId : String,
name : String,
price : String,
status : String
}],
tax : String,
total : String,
status : String,
orderNote : String
}
]
}
As you can see we are storing _id of products which is a subdocument of categories in orders
when storing there is no issue obviously, when it comes to fetch these data if we just need the limited field like name or price there will be no issue as well, but if later on we need some extra fields from products like description,... they are not stored in orders.
My question is this:
Is there any easy way to access other fields of products apart from loop through the whole categories in mongodb, namely I need a sample code for querying the description of a product by only having its _id in mongodb?
or our design and implementation was wrong and I have to re-design it from scratch and separate the products from categories into another collection?
please don't put links to websites or weblogs that generally talks about mongodb and its collections implementations unless they focus on a very similar issue to mine
thanks in advance
I'd assume that you'd want to return as many product descriptions as matched the current list of products, so first, there isn't a query to return only matching array elements. Using $elemMatch you can return a specific element or the first match, but not only matching array elements. However, $elemMatch can also be used as a projection operator.
db.categories({ "products._id" : "PID1" },
{ $elemMatch : { "products._id" : "PID1" },
"products._id" : 1,
"products.description" : 1})
You'd definitely want to index the "products._id" field to achieve reasonable performance.
You might consider instead creating a products collection where each document contains a category identifier, much like you would in a relational database. This is a common pattern in MongoDb when embedding doesn't make sense, or complicates queries and aggregations.
Assuming that is true:
You'll need to load the data from the second collection manually. There are no joins in MognoDb. You might consider using $in which takes a list of values for a field and loads all matching documents.
Depending on the driver you're using to access MongoDb, you should be able to use the projection feature of find, which can limit the fields returned for a document to just those you've specified.
As product descriptions ardently likely to change frequently, you might also consider caching the values for a period on the client (like a web server for example).
db.products.find({ _id: { $in : [ 'PID1', 'PID2'] } }, { description : 1 })

Can you do group by as map reduce in Mongo?

I have two collections. "people" are connected with a "location" like so:
location_id = ObjectId()
db.people.insert(
{
_id : ObjectId(),
name : "Nick",
location : location_id
});
db.locations.insert(
{
_id : location_id,
city : "Cape Town"
});
I would like to create a histogram of locations giving the count of people in each city. But I can't seem to do it with the Mongo group command because they are different collections. Is the correct way to do it with map/reduce?
map-reduce also won't help you here. It also operates on a single collection.
It seems to me that you're trying to apply your relational design skills here. Don't do that. MongoDB requires a fresh approach.
If I were you, I'd probably denormalize location into people collection.
db.people.insert(
{
_id : ObjectId(),
name : "Nick",
location : {city: "Cape Town"}
});
This way it's possible to analyze this data with map-reduce, because everything is in the same collection.