MongoDB - Autocomplete - Get all words starting with X

为君一笑 提交于 2021-01-29 17:56:23

问题


I have a collection (users) with the following structure:

{
   propA: {
        words: ["i", "have", "an","important", "question"]
   }
}

I want to get autocomplete options from the db for some input in my website. So first, i think that i need to create an index for propA.words. Maybe something like this(?):

db.users.createIndex({ "propA.words" : 1 })

Second, how can i query this index to get all the words starting with X? For example, for the string "i", the query will retrieve ["i", "important"].

Thanks!

EDIT: This is the collection:

{
    propA: {
        words: ["aa","bb","cc","dd"]
    }
}
{
    propA: {
        words: ["ab"]
    }
}
{
    propA: {
        words: []
    } 
}
{
    propB: []
}

Now, i want a query to get all the words that starts with "a". The query should return ["aa","ab"] on the above collection. I want the query to use only the index so the search will be efficient.


回答1:


You can use this aggregation, which iterates over the words array and matches the regex search string.

db.collection.aggregate( [
  { 
    $addFields: { 
        matches: { 
            $filter: { 
                input: "$propA.words", 
                as: "w",
                cond: {
                    $regexMatch: { input: "$$w" , regex: "^i"  } 
                }
            } 
        } 
    } 
  }
] )

The output:

{
        "_id" : 1,
        "propA" : {
                "words" : [
                        "i",
                        "have",
                        "an",
                        "important",
                        "question"
                ]
        },
        "matches" : [
                "i",
                "important"
        ]
}


[ EDIT ADD ]

Now, i want a query to get all the words that starts with "a". The query should return ["aa","ab"] on the above collection. I want the query to use only the index so the search will be efficient.

The aggregation:

db.collection.aggregate( [
  { 
      $match: { "propA.words": { $regex: "^a" } } 
  },
  { 
      $unwind: "$propA.words" 
  },
  { 
      $group: { 
          _id: null, 
          matchedWords: { 
              $addToSet: { 
                  $cond: [ { $regexMatch: { input: "$propA.words", regex: "^a"  } }, 
                            "$propA.words",  
                            "$DUMMY" ] 
              } 
          } 
      } 
  },
  { 
      $project: { _id: 0 } 
  }
] )

The result:

{ "matchedWords" : [ "ab", "aa" ] }

Index usage:

The index is created on the collection as follows:

db.collection.createIndex( { "propA.words": 1 } )

You can verify the index usage on the aggregation's $match stage by applying the explain and generating a query plan. For example:

db.collection.explain("executionStats").aggregate( [ ... ] )



回答2:


yes you make an index on the field, which is an array. then use regex query - the symbol ^ for 'starts with'... an index on an array field can create a big load... but your query being a 'start-with' is an efficient design....



来源:https://stackoverflow.com/questions/60727003/mongodb-autocomplete-get-all-words-starting-with-x

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!