2015-06-01 26 views
2

findOne()

如果多个文档满足所述查询,该方法返回根据反映的磁盘上的文件的顺序的自然顺序的第一个文档。

我需要一个类似于上面的效果,除非多个文档满足查询,它会返回最早出现在$或数组中的那个。

db.collection.findOne({ 
    $or: [ 
     {"apple": "blah"}, 
     {"orange": "blah"}, 
     {"grape": "blah"} 
    ] 
}) 

例如,如果这些文件都满足上述查询

[ 
    {"apple": "....", "orange": "....", "grape": "blah"}, 
    {"apple": "....", "orange": "blah", "grape": "...."} 
] 

它只返回匹配orange(第二个以上)的文件中,因为orange来在$或阵列grape之前。同样,如果一个文档匹配apple那么该文档将被返回,因为apple在数组中较早出现。如何才能做到这一点?

回答

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()操作与一个计算的字段。