MongoDB filter by array of objectIds - mongodb

I have a document that has a array of ObjectIDs for reference. That array is not an associative array, it's just the ObjectIDS:
{
...
"tags" : [
ObjectId("54744662ae8a0be602568c4f")
]
}
Now I'm trying to filter based on that array, like this:
db.expenses.find({
tags:{
$elemMatch:{ObjectId("547469bb0bde915a05f74299")}
}
})
I know that the projection on the $elemMatch is wrong, but I just don't know how to do it, and Google isn't helping must because most of the examples are for and array of json objects with defined properties.
Does anyone know how to do this?

If I got your problem correctly, this would be the answer
db.expenses.find(
{
tags: {$in : [ObjectId("54744662ae8a0be602568c4f")]}
})

Related

MongoDB : Match with element in an array

I am working on a collection called Publications. Each publication has an array of objectives which are ids. I have also a custom array of objectives hand written. Now, I want to select all the publications that contains at least one element of the custom objectives array in their objectives. How can I do that ?
I've been trying to make this works with '$setIntersection' then '$count' and verify that the count is greater than 0 but I don't know how to implement this.
Example :
publication_1: {
'_id': ObjectId("sdfsdf46543")
'objectives': [ObjectId("1654351456341"), ObjectId("123456789")]
}
publication_2: {
'_id': ObjectId("sdfs216546543")
'objectives': [ObjectId("1654351456341"), ObjectId("46531132")]
}
custom_array = [ObjectId("123456789"), ObjectId("2416315463")]
The mongo query should return publication_1.
You can do like the following:
db.publications.find({
"objectives": {
"$in": [
ObjectId("123456789"),
ObjectId("2416315463")
]
}
})
Notice: "123456789" is not a valid ObjectId so the query itself may not work. Here is the working example
Mongodb playground link: https://mongoplayground.net/p/MbZK99Pd5YR
objectives is an array of objects, I guess you can just query that field directly:
let custom_array = [ObjectId("123456789"), ObjectId("2416315463")];
// You can search the array with $in property.
let result = await Model.find({ objectives: {$in : custom_array} })

Mongo find based on value in array of objects

the documents looks like :
{
name: 'abc',
types: [
{name:'Large',stock:true},
{name:'XLarge',stock:false},
{name:'XXLarge',stock:true}
]
}
I'm trying to figure out the query to return all documents which are out of stock.
Something like : .find({types:{{$nin:{stock:true}}})
Can I somehow do that?
You can query using positional operator like this:
db.collection.find({'types.stock':{$ne:true}})
$nin operator is used for finding elements not in a particular array. $ne (not equal to) is a much better operation in your case.

how to retrieve partial objects from object array in a field in mongodb

I have a mongoose schema like -
db.foo.insert({one:'a',friends:[{two:'b',three:'c'},{two:'d',three:'e'},{two:'f',three:'G'}]})
now what i want is two retrieve only the 'two' part of friends array
that is I want to find an array of all the values of two in each object in friends array
Is such a projection possible in mongodb where in the output looks like -
['b','d','f']
aggregate is your answer
db.foo.aggregate({"$project" : {"two" : "$friends.two"}}).result
there is another way to do that (getting distinct values)
db.foo.aggregate([
{'$project': {
union:{$setUnion:["$friends.two"]}
}
}
]).result;
You can do this with distinct:
db.foo.distinct('friends.two')
Output:
[
"b",
"d",
"f"
]

Updating multiple MongoDB records in Sails.js

I need to update multiple records in mongodb.
From frontend logic , i got the array of id's as below.
ids: [ [ '530ac94c9ff87b5215a0d6e6', '530ac89a7345edc214618b25' ] ]
I have an array of ids as above , i need to update the folder field for all the records in that array.
I tried passing the id's to mongodb query as below , but still that doesn't work.
Post.native(function(err, collection) {
collection.update({
_id : {
"$in" : ids
}
}, { folder : 'X'}, {
multi : true
}, function(err, result) {
console.log(result);
});
});
Please help.
There seem to be two possible problems.
1) your ids array is not an array of ids, it's an array which has a single element which is itself an array, which has two elements. An array of ids would be `[ 'idvalue1', 'idvalue2']
2) your id values inside of arrays are strings - is that how you are storing your "_id" values? If they are ObjectId() type then they are not a string but a type ObjectId("stringhere") which is not the same type and won't be equal to "stringhere".
There is no reason to use the native method in this case. Just do:
Post.update({id : ids}, {folder : 'X'}).exec(console.log);
Waterline automatically does an "in" query when you set a criteria property to an array, and Sails-Mongo automatically translates "id" to "_id" and handles ObjectId translation for you.
Those strings look like the string representation of mongod ObjectIds, so probably what you want to do is turn them into ObjectIds before querying. Assuming you've corrected your problem with the extra level of nesting in the array, that is:
ids = ['530ac94c9ff87b5215a0d6e6', '530ac89a7345edc214618b25']
Then you want to do something like this:
oids = []
for (var i in ids)
oids.push(ObjectId(ids[i]))
db.c.find({_id: {$in: oids}})
Does that fix your problem?

How can I use a $elemMatch on first level array?

Consider the following document:
{
"_id" : "ID_01",
"code" : ["001", "002", "003"],
"Others" : "544554"
}
I went through this MongoDB doc for elemmatch-query & elemmatch-projection, but not able to figure it out how to use the same for the above document.
Could anyone tell me how can I use $elemMatch for the field code?
You'll want to use the $in operator rather than $elemMatch in this case as $in can be used to search for a value (or values) inside a specific field. $in requires a list of values to be passed as an array. Additionally, and for your case, it will find either a single value, or by searching in an array of values. The entire matching document is returned.
For example, you might use it like this:
db.mycodes.find( { code: { $in: ["001"] } } )
Which could be simplified to just be:
db.mycodes.find({ code: "001" })
As MongoDB will look in an array for a single match like above ("001").
Or if you want to search for "001" or "002":
db.mycodes.find( { code: { $in: ["001", "002"] } } )
$in documentation
If you're simply looking to match all documents with an array containing a given value, you can just specify the value on the reference to that array, e.g.
db.mycodes.find( { code: '001' } )
Which thus would return you all documents that contained '001' in their code array