Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to AND and NOT in MongoDB $text search

I apologise in advance if this question has been asked, I searched without finding an answer.

I want to do a search in MongoDB, and I create the index and do something like

db.myCollection.runCommand( "text", { search: "myWord" } )

This works fine.

I can also do

db.myCollection.runCommand( "text", { search: "myWord1 myWord2" } )

and it will search both words.

Can I do the above search by asking that BOTH words be found? (I know I can do a search on the first word and then a search on the second on the result, but I wonder if there is a better way).

Also, is it possible to specify words to be rejected (for example, search for the word "test", but not for "testing").

I would like to know if I can do this in mongoDB without using external tools.

like image 375
user Avatar asked Jun 01 '14 23:06

user


People also ask

How do I exclude fields in MongoDB?

To exclude the _id field from the output documents of the $project stage, specify the exclusion of the _id field by setting it to 0 in the projection document.

How do I search for a query in MongoDB?

Use the $text query operator to perform text searches on a collection with a text index. $text will tokenize the search string using whitespace and most punctuation as delimiters, and perform a logical OR of all such tokens in the search string.

How do I use full-text search in MongoDB?

To start using MongoDB's full-text search capabilities, you must create a text index on a collection. Indexes are special data structures that store only a small subset of data from each document in a collection separately from the documents themselves.


Video Answer


1 Answers

There are a few options that you can use with text search to suit those needs. Consider the following documents:

{ "text" : "cake" }
{ "text" : "sale" }
{ "text" : "sale cake" }
{ "text" : "cake sale" }
{ "text" : "dress sale" }
{ "text" : "cake sale monday" }

The default "list" of words is an or inclusion, but if you wan't an and inclusion you "quote" the words:

db.words.find( { "$text": { "$search": "\"cake\" \"sale\"" } },{_id: 0})
{ "text" : "cake sale" }
{ "text" : "sale cake" }
{ "text" : "cake sale monday" }

If you want to exclude a word then you prefix with -:

db.words.find( { "$text": { "$search": "\"cake\" \"sale\" -monday" } },{_id: 0})
{ "text" : "cake sale" }
{ "text" : "sale cake" }

And if you wanted part of that as an exact phrase then you "quote" the whole phrase:

db.words.find( { "$text": { "$search": "\"cake sale\" -monday" } },{_id: 0})
{ "text" : "cake sale" }

Stemming words though does have an issue, so :

db.words.find( { "$text": { "$search": "test -testing" } },{_id: 0})

Would not actually return a result.

See the documentation on the $text operator for examples. Not all are there at the moment, but it's getting better.

like image 80
Neil Lunn Avatar answered Nov 15 '22 07:11

Neil Lunn