MongoDB: Text search (exact match) using variable
Asked Answered
H

3

6

MongoDB 3.4

I have a value in a variable. val1 = "Fort Minor"

I need to search in a collection stores (with text index on name field) with documents as

db.stores.insert([
     { _id: 1, name: "Java Hut", description: "Coffee and cakes" },
     { _id: 2, name: "Burger Buns", description: "Gourmet hamburgers" },
     { _id: 3, name: "Coffee Shop", description: "Just coffee" },
     { _id: 4, name: "Fort Coffee", description: "Discount clothing" },
     { _id: 5, name: "Java Shopping", description: "Indonesian goods" }
])


when I text search the collection using the variable

db.City.find({$text:{$search: val1}})

it returns the _id : 4 document, since it contains Fort.

I need to do an exact match but using the variable.

The above search should return only when val1 = "Fort Coffee"

Harvester answered 4/5, 2017 at 9:43 Comment(3)
db.City.find({name:val1}) use thisSupervision
But I need to do a text search.Harvester
Too late but this might help someone, you just need to provide search text under quotes. val1 = "\"Fort Coffee\"" <--- inside quotes are escaped db.City.find({$text:{$search: val1}})Casebound
P
15

When you do text search, it has many internal steps like tokenizing your work, analyzing the lowest stem of the word(e.g. to match cooking & coocked as both are derived from basic work "cook"). If you are expecting an exact match, you are not actually looking for a texual search but you are looking for a normal query.

Hence,

If you do this :

db.City.find({$text:{$search: "Fort Minor"}})

It will try to find all documents which have fort, minor, minority, forting etc in it.

If you do below :

db.City.find({ name : "Fort Minor"})

If will give you the document with exact match.

However, here is the catch :

IF you search all lowercase like :

db.City.find({ name : "fort minor"})

It will not give you what you are expecting.

To resolve this, go for regular expression :

db.user.find( { name: /^Fort Minor$/i } );
Peristome answered 4/5, 2017 at 10:12 Comment(7)
I need to use a variable for the comparision. I can not hard code the values.Harvester
You can user variable via concatenation.. this is just an examplePeristome
can I use a variable in the text search query?Harvester
What type of driver you are using to communicate with mongodb? Or you want to accomplish this in mongoshell?Peristome
I am trying using the mongoshell. I used the commands as in the question.Harvester
you can use simple + sing as concatenation operatorPeristome
This works, but bypassing the text index for a slow regex search is not ideal. Just search for "\"Fort Minor\"" instead.Johnnajohnnie
C
6

Answers above are actually not helpful. I also came across the same issue, I found a solution with new template literals of Javascript. here is the solution:

const val1 = "Fort Minor"
const val2 = `\"${val1}\"`
myDatabase.find({$text:{$search: val2}})

For more information on template literals: https://www.w3schools.com/js/js_string_templates.asp

Copalite answered 18/7, 2021 at 10:22 Comment(1)
thanks for the response the same goes for pymongo collection.find({"$text": {"$search": f"\"{word}\""}})Burdelle
H
-1

If you do this :

query = {"$search" :"(\"{}\"".format(val1)}
city = db.City.find({"$text": query})
Highfalutin answered 3/4, 2020 at 22:17 Comment(1)
I think there is an extra parenthesis at the beginning of your search value (before the first escaped quote).Johnnajohnnie

© 2022 - 2024 — McMap. All rights reserved.