mongodb $哪里不工作

时间:2013-11-08 17:15:15

标签: mongodb shell where

我有这种类型的文件:

    {
  "_id":ObjectId("527cedf19df815000700123b"),
  "title":"title question",
  "content": "content question",
  "answer": [
    {
      "_id": ObjectId("527cee379df8155c1300002a"),
      "content": "<p>answer 1<\/p>",
      "total_dislike": NumberInt(10),
      "total_like": NumberInt(20)
    },
    {
      "_id": ObjectId("527d135b9df8152c04005ddd"),
      "content": "<p>answer 2<\/p>",
      "total_dislike": NumberInt(2),
      "total_like": NumberInt(6)
    }
  ]   


}

我想创建一个answer.total_dislike > answer.total_like

的查询

我使用了这个查询:

> db.Question.find( { $where: "this.answer.total_dislike > this.answer.total_like" } );

但它不起作用。如何编写查询以返回answer.total_dislike大于answer.total_like的所有子文档?

3 个答案:

答案 0 :(得分:1)

$where运算符不会像你想的那样深入研究子文档数组。您将需要首先使用不同的运算符。我不确定这是否有效,但你可以尝试这个或它的变体:

db.Question.find(
    { answer: 
        { $elemMatch: 
            { $where: "this.total_dislike > this.total_like" 
            }
        }
    }
);

答案 1 :(得分:1)

由于此查询执行效果不佳(无法使用索引,并且必须针对集合中的每个文档运行),我建议您尽可能预先计算条件的结果并将其存储为新字段。虽然它稍微增加了文档结构的大小,但它会使查询超快,特别是如果字段被索引:

"answer": [
{
  "_id": ObjectId("527cee379df8155c1300002a"),
  "content": "<p>answer 1<\/p>",
  "total_dislike": NumberInt(10),
  "total_like": NumberInt(20),
  "likes_more": Boolean(true)
},

然后:

db.Question.find(
    { answer: 
        { $elemMatch: 
            { likes_more: false }
        }
    }
);

使用NoSQL数据库时,有时您需要稍微考虑一下这个问题。

另一种选择是执行MapReduce,定期更新以反映新的Like / Dislike更改。虽然根据您当前的结构它并不完全相同,但您可以进行相同类型的计算。

答案 2 :(得分:0)

为什么不使用聚合框架?

 db.Question.aggregate(  
        {$unwind:"$answer"}, 
        {$project:{disliked:{$cond:[{$gt:[{"$answer.total_dislike","$answer.total_like"}], true, false]}, 
                   title:1}
        }, 
        {$match:{disliked:true}}
 )