0

I'm trying to do something like this:

select * from table where not (a=3 and b=4 and c=3 or x=4)

I would expect this to work:

db.table.find( { 
   $not : { 
      $or : [
         { $and : [ { a : 3 },
         { b : 4 },
         { c : 3 } 
      ] } ,
      { x : 4 }
   } 
 } )

But it does not work.

I have read this article

And something like this: {a : { $ne : 3}, b : { $ne : 4} ...}. does not suit me.

Because: my program takes DIFFERENT queries like this (a=3 and b=4 and c=3 or x=4) from users (queries to multilevel embedded objects and arrays). And to write procedure, which automatically apply $not to those queries looks long and thankless task. have you any ideas?

P.S. Why does mongo not have a simple way to do that?
For example, to find all the documents that match the condition, and to take from the collection of the remaining documents?

3
  • Please properly indent your commands when you put them here. Its very hard to read a long JSON object in a single line. Also, what does not work? What is the output you are getting and what are you expecting to get? Commented Dec 16, 2015 at 16:26
  • Thank you for answer. I am a beginner in mongo. And all seems very strangely. So 2 days i study how can i make 2 easy things: 1) i have 1 script for different collections and would like to add all fields in $project automatically and add to them computed fields. For example: my collection is like this: Commented Dec 18, 2015 at 4:01
  • david, in stackoverflow i am at first time. Help below cannot help, how can i break lines in comments ( So, i can not here "properly indent my commands" ( Commented Dec 18, 2015 at 4:16

1 Answer 1

0

For reasons that are likely no longer important, mongoDB did not implement a $not operator for the "old" find() syntax -- only $nor with a list. Your expression works with a $nor list of len 1:

db.foo.find(
    { $nor : [
      { $or : [
          { $and : [ { a : 3 }, { b : 4 }, { c : 3 } ] } ,
          { x : 4 }
      ]
      }
    ]}
);

Going forward, I recommend switching to the agg framework because your query functions flexibility is much greater. Here is your query in the agg framework:

db.foo.aggregate([
    {$match: {$expr: // $expr "enables" full agg framework ops and funcs
              {$not:
                {$or: [
                  {$and: [
                      {$eq:['$a',3]},{$eq:['$b',4]},{$eq:['$c',3]}
                  ]}
                  ,{$eq:['$x',4]}
        ]}
              }
     }}
]);

It's a little more verbose but worth it. Note also that unary function $not is available.

UPDATED

Um --- just realized the original post was 9 years old with no responses; the editing bumped it up the list. Maybe the OP is MongoDB expert now.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.