How to invert a query in mongodb: $not - mongodb

The mongo documentation says the $not operator does what I want, but it doesn't seem to be working:
The following returns a single document:
db.user.find({_id:ObjectId("51f09113cc0bd4a4a3958c96")})
This returns all 27 documents:
db.user.find()
This returns no documents:
db.user.find({$not:{_id:ObjectId("51f09113cc0bd4a4a3958c96")}})
So what am I doing wrong?

You should use $ne:
db.user.find({"_id" : {$ne: ObjectId("51f09113cc0bd4a4a3958c96") }})

Use $ne
db.user.find(_id: {$ne: ObjectId("51f09113cc0bd4a4a3958c96")})

Related

$or operator in MongoDB

Does MongoDB have priorities when using $or operator ? For instance , a query like that :
{$or : [ {id: {$in: arr_firstChild}},{id: {$in: arr_secondChild}}]}
I checked and it returned the longer array(is arr_secondChild and it had more elements than that one). But it makes sense at all ? I can't find anything about it in MongoDB documentation.

How to find document by parts of ObjectId?

For some reason I use MongoDB native ObjectId as primary key for ticket identification number for my application. Is it possible to search documents with ObjectId parts?
For example: I have documents:
[
{_id: ObjectId("577f8e6537e4a676203c056a")},
{_id: ObjectId("577f8ee437e4a676203c0577")},
{_id: ObjectId("577f8f3d717b6fdd22a1684c")}
]
And I want to query it by its _id contains "0577" so that it returns
{_id: ObjectId("577f8ee437e4a676203c0577")}
I have tried regex before. It returned []
db.transaction.find({_id: /0577/i}) ---> return 0
db.transaction.find({_id: {$regex: /0577/, $options: "i"}}) ---> return 0
I think you can use $where like this:
db.transaction.find({ $where: "this._id.str.match(/.*0577/)" })

How to construct aggregation of $setIsSubset with mgo

I tried to construct a pipeline with mgo, but I have no idea about how to use $setIsSubset operator.
Here is the example from mongodb doc shows the usage of $setIsSubSet.
Is there anyone who can give me some tips? :-)
<code>
db.experiments.aggregate(
[
{$project: {A:1, B:1,AisSubset: {$setIsSubset: ["$A", "$B"]}, _id:0 }}
]
)
</code>
mongodb doc

Remove fields from elements of inner array in MongoDB

Say I have:
db.test.insert({foos: [{bars: [{}, {}]}]});
db.test.insert({foos: [{bars: [{}, {}]}]});
Now I want to remove all bars-fields of all foos. How do I do that?
db.test.update({}, {$unset: {"foos.bars": 1}});
and
db.test.update({}, {$pull: {"foos.bars": {}}});
doesn't do anything.
db.test.update({}, {$pull: {"foos.$.bars": {}}});
gives error:
"Cannot apply the positional operator without a corresponding query field containing an array."
Any help highly appreciated.
Adding an exist-query on the subdocument in the array seemed to do the trick:
db.test.remove();
db.test.insert({foos: [{bars: [{"baz": 1} ]}]});
db.test.insert({foos: [{bars: [{"baz": 1} ]}]});
db.test.find({'foos.bars': {$exists: true}}).count();
db.test.update({'foos.bars': {$exists: true}}, {$unset: {'foos.$.bars': 1}}, false, true);
db.test.find({'foos.bars': {$exists: true}}).count();

Conditions in MongoDb

What's the correct way to use operations such as $not or $ne with complex values? I mean values, which are also computed with some operations. I've tried {$not: {$and: [{field1: 'a'}, {field2: 'b'}]}} and {$not: [{$and: [{field1: 'a'}, {field2: 'b'}]}]}, but none of them seem to work correctly. The same with $ne: {$ne: [field1, field2]}. The documentation shows their usage examples as field1: {$not: {$gt: 5}}, and it's nice for so simple cases, but how to deal with more complex ones?
If it makes a difference, I want to use them in a $match clause of the aggregation framework, not just in a find().
UPD:
For example, i'd want to run such query: db.test.aggregate({$match: {$not: {$and: [{f1: 'a'}, {f2: 'b'}]}}}), but it give error "invalid operator: $and" (the same code without $not works). To test that query insert documents before: db.test.insert({f1:'a', f2:'b'}); db.test.insert({f1:'b', f2:'c'}).
$not and $ne are field-specific operators, so you can't apply them to a multi-field query operation. I don't think you can construct a generalized 'negative' query like you're trying to do.
Instead, you'd need to invert your logic field by field to use a query like:
db.test.aggregate({$match: {$or: [{f1: {$ne: 'a'}}, {f2: {$ne: 'b'}}]}})