我有一个搜索功能如下:
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')
}]
}]
})
})
我遇到的问题是我无法优先考虑我给出的这些不同属性之间的结果。他们都混在了一起。无论如何要指明接下来会发生什么?
答案 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" } })
这不仅会搜索索引中设置的所有字段,还会根据匹配字词的字段来指定“相关性”。
根据需要和任何值分配尽可能少的“权重”,但“更高”会增加更多相关性,并首先将结果排序为更多相关性。
因此,能够使用索引会提高效率,而且编码也更容易,您可以将相关性分配到匹配项的位置。