1

我有这种类型的文件:

    {
  "_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)
    }
  ]   


}

我想创建一个查询 where answer.total_dislike > answer.total_like.

我使用了这个查询:

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

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

4

3 回答 3

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,以反映新的喜欢/不喜欢的变化。虽然考虑到您当前的结构,它并不完全相同,但您可以进行相同类型的计算。

于 2013-11-08T18:11:01.807 回答
0

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

db.Question.find(
    { answer: 
        { $elemMatch: 
            { $where: "this.total_dislike > this.total_like" 
            }
        }
    }
);
于 2013-11-08T17:26:40.123 回答
0

为什么不使用聚合框架?

 db.Question.aggregate(  
        {$unwind:"$answer"}, 
        {$project:{disliked:{$cond:[{$gt:[{"$answer.total_dislike","$answer.total_like"}], true, false]}, 
                   title:1}
        }, 
        {$match:{disliked:true}}
 )
于 2013-11-14T09:06:18.557 回答