Mongodb querying from part of object in array - node.js

Here's the sample document I'm trying to query
{
"_id":"asdf0-002f-42d6-b111-ade91df09249",
"user":[
{
"_id":"14bfgdsfg0-3708-46ee-8164-7ee1d029a507",
"n":"aaa"
},
{
"_id":"aasdfa89-5cfe-4861-8a9a-f77428158ca9",
"n":"bbb"
}
]
}
The document has 2 user references and contains the user _id and other misc information. I have the 2 user ids and am trying to get this document via only the user ids. I also don't know the order of the 2 ids. Is this a possible query?
col.findOne({
user:{
$all:[
{
_id:"14bfgdsfg0-3708-46ee-8164-7ee1d029a507"
},
{
_id:"aasdfa89-5cfe-4861-8a9a-f77428158ca9"
}
]
}
})
^^ Something that I've tried that doesn't work.

You are close with your $all attempt.
col.findOne({
"user._id":{
$all : [ "14bfgdsfg0-3708-46ee-8164-7ee1d029a507",
"aasdfa89-5cfe-4861-8a9a-f77428158ca9" ]
}
}
You can query a sub-document by wrapping it quotes. From there $all works against the values you are looking for.
Mongodb find a document with all subdocuments satisfying a condition shows a variation on this type of query.

ElemMatch should do the trick.
col.findOne({user:{$elemMatch:{"_id":"14bfgdsfg0-3708-46ee-8164-7ee1d029a507", "_id":"aasdfa89-5cfe-4861-8a9a-f77428158ca9" }}})

Related

Update a value inside array of objects, inside a document in MongoDB

Here is what my collection looks like
Now suppose I have to update count of 2nd document whose reportTypes.reasonId is 300. I have access to _id as well as reasonId to update the count. I am using Mongoose to query things in my Node application.
What can I try to solve this?
You can do it via arrayFilters:
db.collection.update(
{
managerId:3
},
{
$inc:{"reportTypes.$[x].count":1}
},
{
arrayFilters:[{"x.reasonId":300 }]
}
)
playground
Explained:
Specify the matching document in the query part and create arrayFilter "x" matching the correct reportTYpes array subdocument , in the update part use the $inc operation to increment the count value in the example with 1
you should use dot notation and the $ update operator to do this:
(I'm assuming your collection is called Reason)
var conditions = {
'_id': '6244........',
'reasonTypes.reasonId': 300
}
var update = {
$inc: {
'reasonTypes.$.count': 1
}
};
Reason.update(conditions, update, function(err) {
// Handle error here
})
You can find more on the operator here mongo $ update operator

Delete whole document for matching objectId in array of objects - MongoDB

The structure of my document looks like this in MongoDB :-
{
_id : "7464bbuiecdhbjdje"
client : "MJMK"
users : [
{_id : "1234" , name : "first user"}
]
}
I would like to remove the whole document for matching users._id. In this case, for a user with _id 1234,the whole document needs to be removed. I have been unable to find any efficient function that does this in Node using mongoose. Thanks for your help.
You want to use deleteMany.
This will delete all documents containing the matches query, in this case a user with matching _id in the users array. Our query will be utilizing Mongo's dot notation to access the array like so:
Model.deleteMany({ 'users._id': "1234" })
From the shell following works. Isn't it possible to do the same in node?
db.collectionname.find({ "users": { $elemMatch: { "_id": "1234" } } })
db.collectionname.remove({ "users": { $elemMatch: { "_id": "1234" } } })
Try this:
db.collectionName.remove({"users._id":{_id:"1234"}})

Differences between $or and $in when querying Strings in MongoDB / mongoose

While building an API, I need to match documents that contain pending or active values for the key status.
When trying
args.status = {
$or: [
'active',
'pending'
]
}
I get an error: cannot use $or with string
However,
args.status = {
$in: [
'active',
'pending'
]
}
works just fine.
I would expect $or to work here. Can someone provide context on the differences between the two and why Strings require $in?
$or performs the logical OR operation on an ARRAY with more than two expressions e.g. {$or:[{name:"a"},{name:"b"}]} This query will return the record which are having either name 'a' or 'b'.
$in works on the array and return the documents which are which contains any of the field from your specified array e.g.{name:{$in:['a','b']}} This query will return the documents where name is either 'a' or 'b'.
Ideally both are doing same but just having the syntax difference.
In your case you have to modify your OR query syntax and add the condition expessions in an ARRAY.
{ $or: [
{
"args.status": "active"
},
{
"args.status": "pending"
}
]
}
Thats because $or expects array of objects. Objects that defines some filters out of which at least one needs to be match to return the result. For your particular scenario $in is the best option. Still if you wanna go with $or, the query will be like:
{
$or: [
{'args.status' : {$eq: 'active'}},
{'args.status' : {$eq: 'pending'}}
]
}
I'd suggest you stick with $in as it is the best fit for your requirement.
You can check the official docs for more details on $or
Hope this helps :)

Query/Find MongoDB documents with series of multiple conditions

I have a User schema with basic fields which include interests, location co-ordinates
I need to perform POST request with a specific UserId to get the results
app.post('api/users/search/:id',function(err,docs)
{ //find all the documents whose search is enabled.
//on documents returned in above find the documents who have atleast 3 common interests(req.body.interests) with the user with ':id'
// -----OR-----
//find the documents who stay within 'req.body.distance' compared to location of user with':id'
//Something like this
return User
.find({isBuddyEnabled:true}),
.find({"interests":{"$all":req.body.interests}}),
.find({"_id":req.params.id},geoLib.distance([[req.body.gcordinates],[]))
});
Basically i need to perform find inside find or Query inside query..
As per your comments in the code you want to use multiple conditions in your find query such that either one of those condition is satisfied and returns the result based on it. You can use $or and $and to achieve it. A sample code with conditions similar to yours is given below.
find({
$or:[
{ isBuddyEnabled:true },
{ "interests": { "$all":req.body.interests }},
{ $and:[
{ "_id":req.params.id },
{ geoLib.distance...rest_of_the_condition }
]
}
]
});

how to create user defined id in mongodb rather then _id

I have a schema to add the book details i wanted to maintain a user defined id called book_id rather than mongodb _id ,
To do that i was making a service call to find the total number documents in the collection and was increment the response by 1 and then assign to book_id
Is there a way to do it only in the server side like we use auto-increment in MySQL
you can define your own _id pattern. also you can add incremental values to _id field of a mongodb collection. but you can't use any field instead of _id. because mongodb cares _id for preventing duplication. mongodb's approach is different any rdbms. but if you want to use book_id, you can use as a field. but a mongodb collection always have _id field.
for your answer, you can read this document.
also in here you can find official mongodb sequence/auto-increment information.
you can apply this code on mongo shell.
db.book_counters.insert(
{
book_id: "bookid",
seq: 0
}
)
function getNextSequence(book) {
var ret = db.book_counters.findAndModify(
{
query: { book_id: book },
update: { $inc: { seq: 1 } },
new: true
}
);
return ret.seq;
}
db.book.insert(
{
book_id: getNextSequence("bookid"),
book: "Harry Potter"
}
)
db.book.insert(
{
book_id: getNextSequence("bookid"),
book: "LOTR"
}
)

Resources