是否有一个函数/方法在mongoose(和或mongodb)可用于排序查询结果基于相关性(匹配查询参数的最高数量)?
下面的例子是我目前使用的(查询使用$in:[]
,其他方面相同)-我的集合相当小,所以性能很好,但在较大的集合上,它会显着减慢速度。
或者,如果有一个更好的执行方法(mongoose/mongodb之外),我很乐意知道它。
的例子:
var docs = [
{
fruits: ['apple', 'orange', 'tomato'],
colors: ['blue', 'green'],
// relevance: 3
},
{
fruits: ['apple', 'carrot'],
colors: ['red', 'green'],
// relevance: 2
}
]
var query = {fruits: ['apple', 'orange'], colors: ['green']}
docs.forEach(function(doc){
var relevance = 0
Object.keys(query).forEach(function(_query){
var arrays = [doc[_query], query[_query]]
var result = arrays.shift().filter(function(v) {
return arrays.every(function(a) {
return a.indexOf(v) !== -1;
});
});
relevance += result.length
})
doc.relevance = relevance
})
结果:
var docs = [
{
fruits: ['apple', 'orange', 'tomato'],
colors: ['blue', 'green'],
relevance: 3
},
{
fruits: ['apple', 'carrot'],
colors: ['red', 'green'],
relevance: 2
}
]
您可以使用聚合:
db.getCollection('docs').aggregate([
{$match: {fruits: {$in: ['apple', 'orange']}, colors: {$in: ['green']}}},
{$project: {
relevance: {
$sum: [
{$cond: {if: { "$setIsSubset": [['orange'], "$fruits" ]}, then: 1, else: 0}},
{$cond: {if: { "$setIsSubset": [['apple'], "$fruits" ]}, then: 1, else: 0}},
{$cond: {if: { "$setIsSubset": [['green'], "$colors" ]}, then: 1, else: 0}}]
},
doc: '$$ROOT'}}
])
结果:/* 1 */
{
"_id" : ObjectId("57be8a9b65d2835e960df543"),
"relevance" : 3,
"doc" : {
"_id" : ObjectId("57be8a9b65d2835e960df543"),
"fruits" : [
"apple",
"orange",
"tomato"
],
"colors" : [
"blue",
"green"
]
}
}
/* 2 */
{
"_id" : ObjectId("57be8aa865d2835e960df544"),
"relevance" : 2,
"doc" : {
"_id" : ObjectId("57be8aa865d2835e960df544"),
"fruits" : [
"apple",
"carrot"
],
"colors" : [
"red",
"green"
]
}
}