Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
554 views
in Technique[技术] by (71.8m points)

search - Query MongoDB with $and and Multiple $or

As stated in the documentation, this is not possible.


AND Queries With Multiple Expressions Specifying the Same Operator

Consider the following example:

db.inventory.find( {
    $and : [
        { $or : [ { price : 0.99 }, { price : 1.99 } ] },
        { $or : [ { sale : true }, { qty : { $lt : 20 } } ] }
    ]
} )

This query will return all select all documents where:

the price field value equals 0.99 or 1.99, and the sale field value is equal to true or the qty field value is less than 20.

This query cannot be constructed using an implicit AND operation, because it uses the $or operator more than once.


What is a workaround to query something like this? This query returns no results on MongoDB 3.2. I have tested the $or blocks separately and they are working fine, but not when they are wrapped in $and block. I assumed I didn't read the documentation incorrectly that this is not supposed to work. The only alternative I have is to push the data to ElasticSearch and query it there instead, but that's also just a workaround.

{
    "$and": [
        {
            "$or": [
                {
                    "title": {
                        "$regex": "^.*html .*$",
                        "$options": "i"
                    }
                },
                {
                    "keywords": {
                        "$regex": "^.*html .*$",
                        "$options": "i"
                    }
                }
            ]
        },
        {
            "$or": [
                {
                    "public": true
                },
                {
                    "domain": "cozybid"
                }
            ]
        }
    ]
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

the documentation doesn't say that this is impossible. It only says

This query cannot be constructed using an implicit AND operation, because it uses the $or operator more than once.

this means that this will work :

db.inventory.find( {
    $and : [
        { $or : [ { price : 0.99 }, { price : 1.99 } ] },
        { $or : [ { sale : true }, { qty : { $lt : 20 } } ] }
    ]
} )

but this won't, because it's an implicit $and with two $or

db.inventory.find({
        { $or : [ { price : 0.99 }, { price : 1.99 } ] },
        { $or : [ { sale : true }, { qty : { $lt : 20 } } ] }
})

try it online: mongoplayground.net/p/gL_0gKzGA-u

Here is a working case with an implicit $and:

db.inventory.find({ price: { $ne: 1.99, $exists: true } })

I guess the problem you're facing is that there is no document matching your request in your collection


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...