Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB - Difference between index on text field and text index?

For a MongoDB field that contains strings (for example, state or province names), what (if any) difference is there between creating an index on a string-type field :

db.ensureIndex( { field: 1 } )

and creating a text index on that field:

db.ensureIndex( { field: "text" }

Where, in both cases, field is of string type.

I'm looking for a way to do a case-insensitive search on a text field which would contain a single word (maybe more). Being new to Mongo, I'm having trouble distinguishing between using the above two index methods, and even something like a $regex search.

like image 224
russdot Avatar asked Jun 19 '14 20:06

russdot


People also ask

What is a text index in MongoDB?

MongoDB provides text indexes to support text search queries on string content. Text indexes can include any field whose value is a string or an array of string elements. A collection can only have one text search index, but that index can cover multiple fields.

How many types of indexing are there in MongoDB?

To support efficient queries of geospatial coordinate data, MongoDB provides two special indexes: 2d indexes that uses planar geometry when returning results and 2dsphere indexes that use spherical geometry to return results.

Does MongoDB index every field?

Every document is indexed on every field, even nested fields inside arrays or objects. Rockset indexes every field automatically so users don't need to build indexes to make queries fast — queries are indexed by default. There is no limit to the number of fields which can be ingested and indexed.

Which is the index used for multiple fields in MongoDB?

MongoDB supports compound indexes, where a single index structure holds references to multiple fields [1] within a collection's documents.


2 Answers

The two index options are very different.

  • When you create a regular index on a string field it indexes the entire value in the string. Mostly useful for single word strings (like a username for logins) where you can match exactly.

  • A text index on the other hand will tokenize and stem the content of the field. So it will break the string into individual words or tokens, and will further reduce them to their stems so that variants of the same word will match ("talk" matching "talks", "talked" and "talking" for example, as "talk" is a stem of all three). Mostly useful for true text (sentences, paragraphs, etc).

    Text Search

    Text search supports the search of string content in documents of a collection. MongoDB provides the $text operator to perform text search in queries and in aggregation pipelines.

    The text search process:

    tokenizes and stems the search term(s) during both the index creation and the text command execution.
    assigns a score to each document that contains the search term in the indexed fields. The score determines the relevance of a document to a given search query.
    

    The $text operator can search for words and phrases. The query matches on the complete stemmed words. For example, if a document field contains the word blueberry, a search on the term blue will not match the document. However, a search on either blueberry or blueberries will match.

  • $regex searches can be used with regular indexes on string fields, to provide some pattern matching and wildcard search. Not a terribly effective user of indexes but it will use indexes where it can:

    If an index exists for the field, then MongoDB matches the regular expression against the values in the index, which can be faster than a collection scan. Further optimization can occur if the regular expression is a “prefix expression”, which means that all potential matches start with the same string. This allows MongoDB to construct a “range” from that prefix and only match against those values from the index that fall within that range.

http://docs.mongodb.org/manual/core/index-text/

http://docs.mongodb.org/manual/reference/operator/query/regex/

like image 105
John Petrone Avatar answered Oct 12 '22 00:10

John Petrone


text indexes allow you to search for words inside texts. You can do the same using a regex on a non text-indexed text field, but it would be much slower.

Prior to MongoDB 2.6, text search operations had to be made with their own command, which was a big drawback because you coulnd't combine it with other filters, nor treat the result as a common cursor. As of now, the text search is just another another operator for the typical find method and that's super nice.

So, Why is a text index, and its subsequent searchs faster than a regex on a non-indexed text field? It's because text indexes work as a dictionary, a clever one that's capable of discarding words on a per-language basis (defaults to english). When you run a text search query, you run it against the dictionary, saving yourself the time that would otherwise be spent iterating over the whole collection.

Keep in mind that the text index will grow along with your collection, and it can use a lot of space. I learnt this the hard way when using capped collections. There's no way to cap text indexes.

A regular index on a text field, such as

db.ensureIndex( { field: 1 } )

will be useful only if you search for the whole text. It's used for example to look for alphanumeric hashes. It doesn't make any sense to apply this kind of indexes when storing text paragraphs, phrases, etc.

like image 10
ffflabs Avatar answered Oct 11 '22 23:10

ffflabs