我有这个用户集合:
{
"_id" : ObjectId("501faa18a34feb05890004f2"),
"username" : "joanarocha",
}
{
"_id" : ObjectId("501faa19a34feb05890005d3"),
"username" : "cristianarodrigues",
}
{
"_id" : ObjectId("501faa19a34feb05890006d8"),
"username" : "anarocha",
}
当我查询时:
db.users.find({'username': /anaro/i})
结果按自然顺序(插入顺序)排序。
我想按照相似搜索词顺序对它们进行排序。在这种情况下,结果应按以下顺序返回:
{ "_id" : ObjectId("501faa19a34feb05890006d8"), "username" : "anarocha", } { "_id" : ObjectId("501faa18a34feb05890004f2"), "username" : "joanarocha", } { "_id" : ObjectId("501faa19a34feb05890005d3"), "username" : "cristianarodrigues", }
不幸的是,MongoDB 默认不支持全文搜索排名。
首先,您需要一个算法来计算字符串之间的相似度。请参阅以下链接:
然后您需要编写一个 javascript 函数,使用该算法来比较两个字符串以将其传递到您的查询中。请参阅以下链接了解如何实现这一目标:
$indexOfCP (aggregation)
搜索字符串中是否出现子字符串并返回 UTF-8 代码点 第一次出现的索引(从零开始)。如果未找到子字符串,则返回 -1。
db.testText1.aggregate([
{
$match: {
username: { $regex: "anaro", $options: "i" }
}
},
{
$addFields: {
relevance: {
$indexOfCP: [ { $toLower: "$username" }, "anaro" ] // query
}
}
},
{
$sort: { relevance: 1 } // sort by relevance
},
{
$project: { relevance: 0 } // remove relevance from results
}
])
$match
阶段使用正则表达式来匹配名称。$addFields
阶段为每个匹配的文档添加了一个名为相关性的新字段,该字段存储“anaro”在名称字段中的起始位置。如果“anaro”是文档中名称字段的开头,则该值为 0,这是最佳匹配。$sort
阶段根据相关性字段的值对匹配的文档进行排序,以确保与搜索内容最接近的文档排名第一。$project
阶段从结果中删除了相关字段,因为它只是一个临时字段,我们不希望它出现在最终结果中。