findOne()
:
如果多个文档满足查询,则此方法根据反映磁盘上文档顺序的自然顺序返回第一个文档。
我需要与上面类似的效果,除非多个文档满足查询,它返回最早出现在$或数组中的文档。
db.collection.findOne({
$or: [
{"apple": "blah"},
{"orange": "blah"},
{"grape": "blah"}
]
})
例如,如果这些文件都满足上述查询
[
{"apple": "....", "orange": "....", "grape": "blah"},
{"apple": "....", "orange": "blah", "grape": "...."}
]
它只会返回与orange
匹配的文档(上面的第二个),因为orange
位于$或数组中的grape
之前。同样,如果文档与apple
匹配,则会返回该文档,因为apple
在数组中较早出现。怎么办呢?
答案 0 :(得分:4)
听起来你基本上想要为每个文档分配一个“得分”,然后只返回一个“得分最高”的文档。一种方法是使用aggregation framework并在初始查询中添加$project
和$sort
阶段。然后你$limit
得到第一个或“最高”分数的结果:
db.collection.aggregate([
{ "$match": {
"$or": [
{ "apple": "blah" },
{ "orange": "blah" },
{ "grape": "blah" }
]
}},
{ "$project": {
"apple": 1,
"orange": 1,
"grape": 1,
"score": {
"$add": [
{ "$cond": [{ "$eq": [ "$apple", "blah" ] }, 5, 0 ] },
{ "$cond": [{ "$eq": [ "$orange", "blah" ] }, 3, 0 ] },
{ "$cond": [{ "$eq": [ "$grape", "blah" ] }, 1, 0 ] }
]
}
}},
{ "$sort": { "score": -1 } },
{ "$limit": 1 }
])
这基本上为您提供了与您查询的项目“最佳匹配”的单一结果。或多或少具有计算字段的.findOne()
操作。