UX Guy
UX Guy

Reputation: 257

How do I combine two $and statements in an $or statement in mongodb?

I'm searching mongodb for all messages from a person A to person B as well as all statements from person B to person A. That way I can make a conversation

from: person A AND to: personB

OR

from: person B AND to personA

// Create a conversation
db.collection('messages', function (err, collection) {
    collection.find(
        { // how do I turn this $and into a two nested $and statements inside $or?
            $and: [{
                receiver: new BSON.ObjectID(req.user._id)
            }, {
                sender: new BSON.ObjectID(req.body.sender)
            }]
        }
    ).sort({
        date: -1
    }).toArray(function (err, docs) {
        console.log(docs);
    })
});

Upvotes: 2

Views: 499

Answers (3)

marcinn
marcinn

Reputation: 1786

Try this

db.collection('messages', function (err, collection) {
    collection.find(
        {  $or: [
                    {$and: [{ receiver: new BSON.ObjectID(req.user._id)}, {sender: new BSON.ObjectID(req.body.sender)}]}
                    {$and: [{ receiver: new BSON.ObjectID(req.body.sender)}, {sender: new BSON.ObjectID(req.user._id)}]}
        ]
}).sort({
        date: -1
    }).toArray(function (err, docs) {
        console.log(docs);
    }) });

Upvotes: 1

Nicolas Rinaudo
Nicolas Rinaudo

Reputation: 6178

I'm unfamiliar with the collection function you're calling and do not know what the req object you're referring to is, so take my answer with a grain of a salt.

It seems to me that you're making this much more complicated than it really needs to be. Your $and statement is trivial enough that it does not need the $and keyword:

collection.find({
    receiver: req.user._id,
    sender:   req.body.sender
})

Now, $and and $or work exactly the same way: they take an array of objects. So let's write what I assume you intended your query to be:

collection.find({
    $or: [{
        receiver: req.user._id,
        sender:   req.body.sender
    }, {
        receiver: req.body.sender,
        sender:   req.user_id
    }]
})

Upvotes: 2

Disposer
Disposer

Reputation: 6371

The answer should be something like this:

db.collection('messages', function (err, collection) {
    collection.find(
        { 
        $or : [         
            {$and: [{
                receiver: new BSON.ObjectID(req.user._id)
            }, {
                sender: new BSON.ObjectID(req.body.sender)
            }]},
            {$and: [{
                receiver: new BSON.ObjectID(req.body.sender)
            }, {
                sender: new BSON.ObjectID(req.user._id)
            }]},
        ]
        }
    ).sort({
        date: -1
    }).toArray(function (err, docs) {
        console.log(docs);
    })
});

Upvotes: 3

Related Questions