Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongoDB prefix wildcard: fulltext-search ($text) find part with search-string

I have mongodb with a $text-Index and elements like this:

{    foo: "my super cool item" } {    foo: "your not so cool item" } 

If i do search with

mycoll.find({ $text: { $search: "super"} }) 

i get the first item (correct).

But i also want to search with "uper" to get the fist item - but if i try:

mycoll.find({ $text: { $search: "uper"} }) 

I dont get any results.

My Question: If there is a way to use $text so its finds results with a part of the searching string? (e.g. like '%uper%' in mysql)

Attention: I dont ask for a regex only search - i ask for a regex-search within a $text-search!

like image 379
mdunisch Avatar asked Jun 21 '14 15:06

mdunisch


People also ask

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 search for a string 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 do a full-text search in MongoDB?

Implement full-text search in MongoDB AtlasGo to any cluster and select the “Search” tab to do so. From there, you can click on “Create Search Index” to launch the process. Once the index is created, you can use the $search operator to perform full-text searches.

How does MongoDB text search work?

MongoDB text search uses the Snowball stemming library to reduce words to an expected root form (or stem) based on common language rules. Algorithmic stemming provides a quick reduction, but languages have exceptions (such as irregular or contradicting verb conjugation patterns) that can affect accuracy.


2 Answers

It's not possible to do it with $text operator.

Text indexes are created with the terms included in the string value or in an array of strings and the search is based in those indices.

You can only group terms on a phrase but not take part of them.

Read $text operator reference and text indexes description.

like image 112
francadaval Avatar answered Sep 22 '22 06:09

francadaval


I don't have enough reputation to comment jasenkoh solution, but this is clearly the best way to deal with this situation.

In OP situation, I would:

db.mycoll.createIndex( { foo: "text" } ) db.mycoll.createIndex( { foo: 1 } ) db.mycoll.find({$or: [{$text: {$search: 'uper'}}, {foo: {$regex: 'uper'}}]}) 

For better performances (but slightly different results), replace the last line with:

db.mycoll.find({$or: [{$text: {$search: 'uper'}}, {foo: {$regex: '^uper'}}]}) 
like image 27
Jean-Baptiste Martin Avatar answered Sep 25 '22 06:09

Jean-Baptiste Martin