优先考虑mongo搜索

时间:2015-07-27 09:25:56

标签: mongodb mongodb-query

我有一个搜索功能如下:

instance.dbInstance.collection('cars', function(error, collection) {
    collection.find({
    $and: [{

        $or: [{
            name: eval('\/' + carName + '\/i')
        }, {
            mid: eval('\/' + carName + '\/i')
        }, {
            last: eval('\/' + carName + '\/i')
        }, {
            ia: eval('\/' + carName + '\/i')
        }, {
            ea: eval('\/' + carName + '\/i')
        }, {
            carno: eval('\/' + carName + '\/i')
        }, {
            cartag: eval('\/' + carName + '\/i')
        }]
    }]
  })
})

我遇到的问题是我无法优先考虑我给出的这些不同属性之间的结果。他们都混在了一起。无论如何要指明接下来会发生什么?

1 个答案:

答案 0 :(得分:1)

你为此提出的语法肯定是“独特的”,但它基本上分解为做一个非常基本的正则表达式搜索,以查看你的搜索词存在于其中一个字段中。

使用$regex,其中被搜索的字符串没有“锚定”到字符串的开头是非常低效的,并且通常需要扫描整个表或者最好是整个索引可用于为了确定匹配。

您需要"text search",它不仅可以进行非常简单的查询,而且效率更高,但它允许您为影响相关性得分的字段指定“权重”。

所以设置索引如下,所有字段名称都设置为“text”类型,然后是每个字段所需的"weights"

db.collection.createIndex(
    {
        "name": "text",
        "mid": "text",
        "last": "text",
        "ia": "text",
        "ea": "text",
        "carno": "text",
        "cartag": "text"
    },
    {
        "weights": {
            "name": 30,
            "mid":  25,
            "last": 20,
            "ia": 15,
            "ea": 10,
            "carno": 5,
            "cartag": 2
        }
    }
)

然后你可以在集合上发出这样的查询:

db.collection.find(
   {  "$text": { "$search": carName } },
   { "score": { "$meta": "textScore" } }
).sort({ "score": { "$meta": "textScore" } })

这不仅会搜索索引中设置的所有字段,还会根据匹配字词的字段来指定“相关性”。

根据需要和任何值分配尽可能少的“权重”,但“更高”会增加更多相关性,并首先将结果排序为更多相关性。

因此,能够使用索引会提高效率,而且编码也更容易,您可以将相关性分配到匹配项的位置。

相关问题