MongoDB fulltext search + workaround for partial word match

前端 未结 5 995
予麋鹿
予麋鹿 2021-02-05 03:51

Since it is not possible to find \"blueberry\" by the word \"blue\" by using a mongodb full text search, I want to help my users to complete the word \"blue\" to \"blueberry\".

相关标签:
5条回答
  • 2021-02-05 04:26

    A simple workaround I am doing right now is to break the text into individual chars stored as a text indexed array.

    Then when you do the $search query you simply break up the query into chars again.

    Please note that this only works for short strings say length smaller than 32 otherwise the indexing building process will take really long thus performance will be down significantly when inserting new records.

    0 讨论(0)
  • 2021-02-05 04:30

    Language stemming in text search uses an algorithm to try to relate words derived from a common base (eg. "running" should match "run"). This is different from the prefix match (eg. "blue" matching "blueberry") that you want to implement for an autocomplete feature.

    To most effectively use typeahead.js with MongoDB text search I would suggest focusing on the prefetch support in typeahead:

    • Create a keywords collection which has the common words (perhaps with usage frequency count) used in your collection. You could create this collection by running a Map/Reduce across the collection you have the text search index on, and keep the word list up to date using a periodic Incremental Map/Reduce as new documents are added.

    • Have your application generate a JSON document from the keywords collection with the unique keywords (perhaps limited to "popular" keywords based on word frequency to keep the list manageable/relevant).

    You can then use the generated keywords JSON for client-side autocomplete with typeahead's prefetch feature:

    $('.mysearch .typeahead').typeahead({
      name: 'mysearch',
      prefetch: '/data/keywords.json'
    });
    

    typeahead.js will cache the prefetch JSON data in localStorage for client-side searches. When the search form is submitted, your application can use the server-side MongoDB text search to return the full results in relevance order.

    0 讨论(0)
  • 2021-02-05 04:40

    Don't know if this might be useful to some new people facing this problem.

    Depending on the size of your collection and how much RAM you have available, you can make a search by $regex, by creating the proper index. E.g:

    db.collection.find( {query : {$regex: /querywords/}}).sort({'criteria': -1}).limit(limit)
    

    You would need an index as follows:

    db.collection.ensureIndex( { "query": 1, "criteria" : -1 } )
    

    This could be really fast if you have enough memory.

    Hope this helps.

    0 讨论(0)
  • 2021-02-05 04:42

    For those who have not yet started implementing any database architecture and are here for a solution, go for Elasticsearch. Its a json document driven database similar to mongodb structurally. It has "edge-ngram" analyzer which is really really efficient and quick in giving you did you mean for mis-spelled searches. You can also search partially.

    0 讨论(0)
  • 2021-02-05 04:46

    You can not query for all the words in the index, but you can of course query the original document's fields. The words in the search index are also not always the full words, but are stemmed anyway. So you probably wouldn't find "blueberry" in the index, but just "blueberri".

    0 讨论(0)
提交回复
热议问题