Return Every Certain Object in MongoDB - mongodb

How to write a query which returns "every" object in the NoSQL database named "address"? ... please note it may be "nested" to other objects.
I tried
.find({
'result.extractorData.data[0].group[0].address': {
$exists: true
}
});
But that didn't work, BTW Data Looks Like:

I think for nested arrays you better to use elemMatch operator
See similar questions here and here
The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.
More on elemMatch
Also another way you can:
.find({
'result.extractorData.data.group.address': {
$exists: true
}
});

Related

expression filters and object filters yield different results when null / undefined is involved

When used in the $match stage, these two aggregation stages return different documents:
$expr: {
$eq: ["$cheese", undefined]
}
{
cheese: {$eq: undefined}
}
The field cheese is not a property of any document in the collection.
In the second query, it returns all documents, which is expected behavior.
In the first query, it returns no documents.
What explains the difference?
Using $expr MongoDB will return always false when compare with undefined as is not a valid value to compare with.
But without $expr mongo uses MongoDB query language (like a find query) which will compare if the field exists.
Is that the reason because using the first query you do not receive anything (the comparsion is always false) and the second query return all documents (the field does not exist so the comparsion is always true).

IN condition is not working in mongoDB

I want to delete some collections from MongoDB based on some conditions.
I am using { $in: deleteModule}, where deletemodule is an array ["ab","bc"].
But its deleting only the record which is existing first in the collection.
myDb.collection('ABC').findAndModify(
{'projectName': projectName, 'companyName': companyName,'moduleName':{ $in: deleteModule}},
[['_id', 'asc']],
{ 'remove': true },
findAndModify can be used to atomically modify a document (at most one) and return it. It will remove only the first matched document. This is how it is implemented.
The official document says so: https://docs.mongodb.com/manual/reference/command/findAndModify/
Use remove for your use case.
Example:
db.users.remove({'_id':{'$in':inactive_users}})
You need to use $in condition to achieve the result
ABC.remove({ moduleName: { $in: deleteModule } })

Use $not or $ne in update query

Should I use $not or $ne in the query:
Mytable.update({ TheThing: Thing,
'UpdatedInfo.NewInfo': {$ne: ThisNewestInfo} }, {
$push: {
UpdatedInfo: {
TheDate: ThisDate,
NewInfo: ThisNewestInfo,
Past: OriginalInfo
}
}
},
function (err, result) {
if (err){
throw new Error(err.message);
}
}
If I only want to update the document when ThisNewestInfo is not already present in UpdatedInfo array, in NewInfo object element. Trying to understand the difference between $not and $ne.
And also:
If the document does not contain UpdatedInfofield in the beginning? How should I change the update query above? Meaning that if UpdatedInfodoes not exists it adds UpdatedInfo, and later on, say next day, checks if ThisNewestInfois not already present when updating document again.
It depends on your collection actually.
The main different between $ne and $not in this scenario is that, $not performs a logical disjunction. That is if your document didn't had an UpdatedInfo field, using $not would have pushed the document while using $ne nothing would have happened to that document.
So if all your document of collection has UpdatedInfo field, its better to go with $ne.
Edit
Based on your edit you mentioned UpdatedInfo might not be present in document. In such cases you should use $not. $ne wont be able to update docs that doesn't have UpdatedInfo field.
Remember like this: $not checks for presence of key as well as value, while $ne checks only for value and ignores document that doesn't have the particular key in query.

MongoDB return specific fields using $nin or $in

I am aware that mongodb allows $elemMatch, $slice and $ aggregators when it comes into returning fields from query but I'm wondering on how to return these fields that I want to be returned. Here's my data:
{_id:'abc',
content:[
{x:1,arr:['123','456'],arr2:[]},
{x:2,arr:['456','789'],arr2:[]},
{x:3,arr:['123','678'],arr2:[{y:1,z:1}]},
{x:4,arr:['123','789'],arr2:[{y:0,z:0}]}
]
}
and I want to return all objects that doesn't contain arr:['123'] and arr2:[{y:1,z:1}]
Any kind of help would be appreciated.

How to force MongoDB pullAll to disregard document order

I have a mongoDB document that has the following structure:
{
user:user_name,
streams:[
{user:user_a, name:name_a},
{user:user_b, name:name_b},
{user:user_c, name:name_c}
]
}
I want to use $pullAll to remove from the streams array, passing it an array of streams (the size of the array varies from 1 to N):
var streamsA = [{user:"user_a", name:"name_a"},{user:"user_b", name:"name_b"}]
var streamsB = [{name:"name_a", user:"user_a"},{name:"name_b", user:"user_b"}]
I use the following mongoDB command to perform the update operation:
db.streams.update({name:"user_name", {"$pullAll:{streams:streamsA}})
db.streams.update({name:"user_name", {"$pullAll:{streams:streamsB}})
Removing streamsA succeeds, whereas removing streamsB fails. After digging through the mongoDB manuals, I saw that the order of fields in streamsA and streamsB records has to match the order of fields in the database. For streamsB the order does not match, that's why it was not removed.
I can reorder the streams to the database document order prior to performing an update operation, but is there an easier and cleaner way to do this? Is there some flag that can be set to update and/or pullAll to ignore the order?
Thank You,
Gary
The $pullAll operator is really a "special case" that was mostly intended for single "scalar" array elements and not for sub-documents in the way you are using it.
Instead use $pull which will inspect each element and use an $or condition for the document lists:
db.streams.update(
{ "user": "user_name" },
{ "$pull": { "streams": { "$or": streamsB } }}
)
That way it does not matter which order the fields are in or indeed look for an "exact match" as the current $pullAll operation is actually doing.