Query model with array in mongodb - arrays

I am new in node and MongoDB.
I am trying to query a model with an array.
The array looks like this
var grArr = [ '5aabc39a3d88101e4b52c861', '5ac3a1fe83d45353bc6a995c' ]
And the query is
Group.find().where({ _id: { $in: grArr }}).exec(function(err,gdoc){
if(err)
{
callback({err:err,message:"Error looking up company"});
}
else
{
console.log(gdoc.companies); //Gives undefined
callback(null,gdoc.companies);
}
});
The query returns undefined.
Any help is highly appreciated.

There is 2 ways to perform a query with mongoose, and it seems to me that you're mixing both of them.
Find should be called with your query as parameter:
And you get something like
Group.find({ _id: { $in: grArr }}, function(err,gdoc){
if(err) {
callback({err: err, message:"Error looking up company"});
}
else {
console.log(gdoc); //Should print all the matching documents since gdoc is an array
callback(null, gdoc.map(doc => doc.companies); //returns every companies of every document
}
});
The Query API of mongoose
This time you can call Find with no parameters and chain the where statement like this
Group.find({}).where('_id').in(grArr).exec(callback)

find() passed array to the callback function. See documentation https://mongoosejs.com/docs/api.html#model_Model.find
gdoc is array. Edit your code like this:
...
callback(null, gdoc[0].companies);
...

Try this,
Group.find({ _id: { $in:arr }).lean().exec().then((result) => {
}, (err) => {
});

Related

How can I realize "find" with using "$in" by two parameters in mangoose?

Hi I have the function which get object with id array like this.
{
"participants": [
"5fa566b5b96a9407c804ccd4",
"5fa5639cb96a9407c804ccce"
]
}
And I need to find object which have exactly this fields
Objects in which i try to find it looks like this:
{
"_id" : ObjectId("5fac288e53a6a72e94f721fa"),
"participants" : [
ObjectId("5fa566b5b96a9407c804ccd5"),
ObjectId("5fa5639cb96a9407c804ccc5")
],
"messages" : [],
}
I am trying to do like this but it doesn't work.
async filterDialog(newDialog: any){
const res = await Dialog.find({
'participants': { $in: { ...newDialog.participants } }, function(err: any, dialog: any) {
if (err) {
return err
} else {
return dialog
}
},
})
return res;
}
Will be glad if someone help me.
I think you need $all operator.
Check this query:
db.collection.find({
"participants": {
"$all": yourArray
}
})
Only return the document where the field participants contains all element from the given array.
Example here where I've used numbers instead of ObjectId to read easier.
Please check if this is the behavior you expect.

Updating Property on Object with MongoDB Without Wiping Out Surrounding Properties

I have a Node/MongoDB backend endpoint that takes a passed in an array of mongo _ids, and then updates a field on the records matching those passed in ids.
if (mongoArrRecords) {
try {
db.collection('clients').updateMany(
{ _id: { $in: mongoArrRecords } },
{ $set: { subscription: { subscriptionEnd: lastDayOfMonth } } },
function (err, res) {
if (err) throw err;
console.log(res);
});
res.sendStatus(200);
} catch (e) {
console.log(e);
}
}
However, what I'm noticing is is that rather than merely updating the property I'm defining with the $set operator, the entire containing object is being wiped out and replaced with this one property.
The data being targeted looks like this (subscription) is an array at the root of the document:
"subscription": [
{
"someProp": value,
"someOtherProp": value,
"subscriptionEnd": "2017-04-30T05:00:00.000Z",
}
],
So my question is: how I can make this update just the field in question, without wiping out the surrounding properties within the object? Because right now, after making my update, the above data looks like this (notice "someProp" and "someOtherProp" are now gone):
"subscription": [
{
"subscriptionEnd": "2018-04-30T05:00:00.000Z",
}
],
If I can't target precisely, the only other option I can imagine is getting the object first, and passing back in that entire object -- though I'm not sure exactly what that would look like. Surely there must be a way to change one property on one object within an array? Yes? No?
Try positional all $[] to target all array elements in 3.6.
db.collection('clients').updateMany(
{ _id: { $in: mongoArrRecords } },
{ $set: { "subscription.$[].subscriptionEnd": lastDayOfMonth } }
)
Target specific element ( 1st element )
db.collection('clients').updateMany(
{ _id: { $in: mongoArrRecords } },
{ $set: { "subscription.0.subscriptionEnd": lastDayOfMonth } }
)
Target element through query filter dynamically
db.collection('clients').updateMany(
{ _id: { $in: mongoArrRecords }, "subscription.someOtherProp":value},
{ $set: { "subscription.$.subscriptionEnd": lastDayOfMonth } }
)

mongodb make dynamic query for sort field options

I'm using aggregate query for showing some results given some code snippets
if (name) {
sort = { '$sort': { name: -1 } }
} else {
sort = ''
}
User.aggregate([sort, { $match: {} }])
Problem is when value of name is not set aggregate query is giving error how to make this aggregate query dynamic in nodejs. I need to fit sort option anywhere depending on filter select by user.
this should work :
var query = [{
$match: {}
}]
if(name)
{
query.unshift({ '$sort': { name: -1 } });
}
User.aggregate(query)

How to pull data from deeply nested array in mongodb?

Hi I have deeply nested array in my mongoose schema. I want to pull record from that deeply nested array. Can anyone please help in writing the moongoose query. I tried this
var condition = {
_id: user,
$and: [
{
'cardInfo.cards': {
$elemMatch: {
_id: cardId,
isActive: '0'
}
}
},
{
'cardInfo.cards': {
$elemMatch: {
_id: { $exists: true }
}
}
}
]
};
var dataToUpdate = {
$pull: {'cardInfo.cards': { _id: cardId }}
};
var options = {
lean: true
}
for schema please look at MyAnotherQuestion and please try to answer that question as well. Above query is not working but in mongodb it is working fine if I use ObjectId for cardId
Ok I have been able to resolve the issue. What I did is just added an another parameter in options variable like:
var options = { strict: false, lean: true}
strict: false is the parameter which made my query to work and my mongoose query is same i.e
Customer.update(condition, dataToUpdate , options, anycallback)
and yes it is working for me.

How to know which array element is present in my database array?

I want to write a query in mongoDB where I want to find which elements of my array are present in database array 'upvotes' my query is given below
userupvotesmodel.findOne({mobile_no: "1234567890", upvotes : { $in : ["aa", "bdnvh", "563fa4408d88ea6c13c7abba", "djfufhgj", "5625bd9dbe545d2412d4ae62", "fjjshddhjfn", "djfhudh", "jfhshnffj", "sjdhfkskajdk"] } }, function(err, docs) {
if (err) {
console.log('Error Finding query results');
console.log(err);
res.json({success: 0, message : err});
return next(err);
} else {
if (docs) {
console.log('2 mins', currentdate.getMinutes());
console.log('2 secs', currentdate.getSeconds());
console.log('docs', docs);
}
}
});
Now for query above if any single value of my array is present in database then it sends whole upvotes array but I am not able to find out which elements were present for e.g "aa", "bdnvh" etc in database how can I write a query to know which elements are present in the database.
I want to find this in one query by querying for every single element; I know I can do this but I want to do this in any possible single mongoDB query.
I think you don't need to worry about the query and you can just use java script instead. Just iterate through the docs.upvotes array and compare its values with the array you provided.
var my_array = ["aa", "bdnvh", "563fa4408d88ea6c13c7abba", "djfufhgj", "5625bd9dbe545d2412d4ae62", "fjjshddhjfn", "djfhudh", "jfhshnffj", "sjdhfkskajdk"];
// ... your code
// inside of if(docs) statement
var matched_elements = [];
docs.upvotes.forEach(function(element, index, array) {
for (var i = 0; i < my_array.length; i++) {
if (my_array[i] == element) {
matched_elements.push(element);
}
}
});
console.log(matched_elements);
You could use the aggregation framework. First $unwind your upvotes array. Then $match on elements that are in the array provided by you. Than $group it back on _id(or whatever you want) creating "matched_elements" array with $addToSet or $push. The returned documents will have only upvotes elements (in "matched_elements array) that are also in your array.
var my_array = ["aa", "bdnvh", "563fa4408d88ea6c13c7abba", "djfufhgj", "5625bd9dbe545d2412d4ae62", "fjjshddhjfn", "djfhudh", "jfhshnffj", "sjdhfkskajdk"];
db.collection.aggregate( [
{ "$unwind" : "$upvotes" },
{ "$match": { "upvotes": {"$in": my_array} } },
{ "$group" : { "_id":"$_id","matched_elements":{ "$addToSet": "$upvotes" }}}
] );

Resources