Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple $regex using $and in MongoDB

Tags:

regex

sql

mongodb

I have some collection with the next records:

{
    "_id" : ObjectId("52b18fb2a21351b2bb29dfc7"),
    "title" : "aaa"
}
{
    "_id" : ObjectId("52b18fd0d17d7f69e078f7b7"),
    "title" : "bbb"
}
{
    "_id" : ObjectId("52b18fd3d17d7f69e078f7b8"),
    "title" : "ccc"
}

Next query gives as a result 1 records (with title="aaa") as we expected:

db.test.find({
     {title:{$regex:'aaa'}}
})

But when we use complex condition for $and we got something unexpected:

db.test.find({
    $and: [
        {title:{$regex:'aaa'}},
        {title:{$regex:'bbb'}}
    ]
})

I need query exactly in this case because I'm going to use selection with stop-words, for example:

db.test.find({
    $and: [
        {title:{$regex:'aaa'}},
        {title:{$regex:'bbb'}},
        {title:{$not:/bbb/i}},
    ]
})

Using query that above, I expecting only one field in result (with title="aaa").

I have idea how to solve this issue using aggregate, but I hope there is another way how to solve it.

Thanks!

like image 561
itspoma Avatar asked Dec 18 '13 12:12

itspoma


People also ask

Which operator is used Combine 2 expression in MongoDB?

Logical Operators Joins two or more queries with a logical AND and returns the documents that match all the conditions.

How do I use $regex in MongoDB?

If you want to add a regular expression inside a comma-separated list of a query condition, then you have to use the $regex operator. If you want to use x and s options then you have to use $regex operator expression with $options. Starting from the latest version of MongoDB(i.e., 4.0.

How do I use wildcard search in MongoDB?

Create a Wildcard Index on All Fields With this wildcard index, MongoDB indexes all fields for each document in the collection. If a given field is a nested document or array, the wildcard index recurses into the document/array and stores the value for all fields in the document/array.

How do I find special characters in MongoDB?

To match a special character, precede it with a backslash, like this \* .


2 Answers

Simply build proper regex

pattern "/A AND B/"
pattern "/NOT (NOT A OR NOT B)/"

Regex:

"/^(^A|^B)/"

Or this one

/(?=.*word1)(?=.*word2)/
like image 120
Andrey Yasinishyn Avatar answered Sep 19 '22 21:09

Andrey Yasinishyn


Well, tested using another data and got expected result:

/* 0 */
{
    "_id" : ObjectId("52b18fb2a21351b2bb29dfc7"),
    "title" : "aaa"
}

/* 1 */
{
    "_id" : ObjectId("52b18fd0d17d7f69e078f7b7"),
    "title" : "bbb"
}

/* 2 */
{
    "_id" : ObjectId("52b18fd3d17d7f69e078f7b8"),
    "title" : "ccc"
}

/* 3 */
{
    "_id" : ObjectId("52b19606d17d7f69e078f7b9"),
    "title" : "aaa test"
}

/* 4 */
{
    "_id" : ObjectId("52b19624d17d7f69e078f7ba"),
    "title" : "aaa test wel"
}

Query:

db.test.find({
    $and: [
        {title:{$regex:'aa'}},
        {title:{$regex:'t'}},
        {title:{$not:/wel/}}
    ]
})

Response:

/* 0 */
{
    "_id" : ObjectId("52b19606d17d7f69e078f7b9"),
    "title" : "aaa test"
}

Perhaps, that issue reproducing only when title and conditions contains cyrillic symbols. Going to to reproduce it now..

like image 22
itspoma Avatar answered Sep 18 '22 21:09

itspoma