您不需要循环查询或任何类似的事情。提交多个项目以使用数据库进行测试称为$or 条件,或者在这种情况下,它可以显式缩短为$in,给定输入列表以匹配类似的值列表。这将返回包含针对比较字段列出的任何值的文档,在这种情况下,它也是一个数组。
唯一需要做的就是将公共元素与公共元素的数量相匹配。这里可以使用聚合框架的$setIntersection 运算符来匹配元素以及$size 以返回匹配列表的大小。
这有效地通过匹配元素对文档“评分”,这些元素可以传递给$sort 以首先返回最多匹配。然后唯一要求的另一件事是“在 10 点停止”,这是 $limit 操作对结果所做的。
作为一个完整的例子:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/test');
var data = [
{ "colors": [ "red", "blue", "green" ] },
{ "colors": [ "yellow", "brown", "green" ] },
{ "colors": [ "purple" ] },
{ "colors": [ "red", "blue", "orange" ] }
];
var colorSchema = new Schema({
"colors": []
});
var Color = mongoose.model('Color',colorSchema);
function findColors(list,callback) {
Color.aggregate(
[
{ "$match": { "colors": { "$in": list } } },
{ "$project": {
"colors": 1,
"score": {
"$size": {
"$setIntersection": [ "$colors", list ]
}
}
}},
{ "$sort": { "score": -1 } },
{ "$limit": 10 }
],
callback
);
}
async.series(
[
function(callback) {
Color.remove({},callback);
},
function(callback) {
async.each(data,function(item,callback) {
console.log(item);
Color.create(item,callback);
},callback);
},
function(callback) {
console.log("here");
findColors(["red","blue","green"],function(err,result) {
console.log(result);
callback(err);
});
}
],
function(err) {
if (err) throw err;
mongoose.disconnect();
}
)
产生输出:
[ { _id: 55ff60dc683554e114f90bf2,
colors: [ 'red', 'blue', 'green' ],
score: 3 },
{ _id: 55ff60dc683554e114f90bf5,
colors: [ 'red', 'blue', 'orange' ],
score: 2 },
{ _id: 55ff60dc683554e114f90bf3,
colors: [ 'yellow', 'brown', 'green' ],
score: 1 } ]
因此,匹配最多的文档位于顶部,匹配较少的文档位于下方。此外,任何与列表不匹配的内容都将被排除在外。