使用mongoose进行mongo $ $和$ sub并且不会产生预期结果

时间:2016-04-04 15:49:09

标签: javascript node.js mongodb mongoose mongodb-query

modelThreader.find({
        $and: [
            {"date_entered": { $lt: fromTime }},
            {"cancelled": { $ne: true }},
            {"hideFromUserIds.id": { $ne: current_user_id }},
            {"banned": false},
            {$and: [
                {"user_id": { $ne: current_user_id }},
                {"privacy": { $ne: 1 }}
            ]}
        ]
    }).exec(function( err, docs ){

   // handle response.

});

我在mongo中看似简单的查询时遇到了麻烦。

上面的查询我需要在查询中设置所有第一批,即:

{"date_entered": { $lt: fromTime }},
{"cancelled": { $ne: true }},
{"hideFromUserIds.id": { $ne: current_user_id }},
{"banned": false},

这正如预期的那样正常。但是,我需要在文档架构发生更改时添加到此查询中。

有一个新字段“privacy”,其中int 1是私有的,只应返回给每个人的用户。正如你从我的查询中看到的那样我想说

{$and: [
   {"user_id": { $ne: current_user_id }},
   {"privacy": { $ne: 1 }}
]}

即,如果current_user_id是请求查询的那个,请不要应用任何隐私过滤器,否则,只返回隐私不是1的文档。

问题在于它将$ ne:1应用于所有用户,包括current_user_id ......

EDIT 我能达到预期效果的唯一方法就是做一个巨大的$或者这样效率很低:

where或是其他user_id的数组

$or: [
                        {$and: [
                            //other people, respecting privacy
                            {$or: or},
                            {"date_entered": { $lt: fromTime }},
                            {"cancelled": { $ne: true }},
                            {"hideFromUserIds.id": { $ne: current_user_id }},
                            {"banned": false},
                            {"user_id":         { $ne: current_user_id }},
                            {"privacy":     { $ne: 1 }}
                        ]},
                        {$and: [
                            //this user, not looking at privacy
                            {"date_entered": { $lt: fromTime }},
                            {"cancelled": { $ne: true }},
                            {"hideFromUserIds.id": { $ne: current_user_id }},
                            {"banned": false},
                            {"user_id": current_user_id }
                        ]}
                    ]})

1 个答案:

答案 0 :(得分:1)

你似乎错过了明显的复合逻辑,其中只有一个“小部分”是等效的$or条件:

modelThreader.find({
  "date_entered": { "$lt": fromTime },
  "cancelled": { "$ne": true },
  "banned": false,
  "$or": [
    { "user_id": current_user_id },
    {
      "user_id": { "$ne": current_user_id },
      "hideFromUserIds.id": { "$ne": current_user_id },
      "privacy": { "$ne": 1 }            
  ]
})

在逻辑中另一个“调整”的地方,"hideFromUserIds.id"current_user_id无关,因为它已经是"user_id",因为它已经是data = list(structure(c(0, 1, 3, 0, -1, 0, -1, 0, -3, 0, 2, 0, 0, 0), .Dim = c(2L, 7L), .Dimnames = list(c("TRIAL1", "severity"), c("ITEM1", "ITEM2", "ITEM3", "ITEM4", "ITEM6", "ITEM7", "ITEM8"))), structure(c(0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0), .Dim = c(2L, 7L), .Dimnames = list(c("TRIAL1", "severity"), c("ITEM1", "ITEM2", "ITEM3", "ITEM4", "ITEM6", "ITEM7", "ITEM8"))), structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), .Dim = c(2L, 7L), .Dimnames = list(c("TRIAL1", "severity"), c("ITEM1", "ITEM2", "ITEM3", "ITEM4", "ITEM6", "ITEM7", "ITEM8"))), structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), .Dim = c(2L, 7L), .Dimnames = list(c("TRIAL1", "severity"), c("ITEM1", "ITEM2", "ITEM3", "ITEM4", "ITEM6", "ITEM7", "ITEM8"))), structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), .Dim = c(2L, 7L), .Dimnames = list(c("TRIAL1", "severity"), c("ITEM1", "ITEM2", "ITEM3", "ITEM4", "ITEM6", "ITEM7", "ITEM8")))) [[1]] ITEM1 ITEM2 ITEM3 ITEM4 ITEM6 ITEM7 ITEM8 TRIAL1 0 3 -1 -1 -3 2 0 severity 1 0 0 0 0 0 0 [[2]] ITEM1 ITEM2 ITEM3 ITEM4 ITEM6 ITEM7 ITEM8 TRIAL1 0 0 2 0 0 0 0 severity 0 0 0 0 0 0 0 [[3]] ITEM1 ITEM2 ITEM3 ITEM4 ITEM6 ITEM7 ITEM8 TRIAL1 0 0 0 0 0 0 0 severity 0 0 0 0 0 0 0 [[4]] ITEM1 ITEM2 ITEM3 ITEM4 ITEM6 ITEM7 ITEM8 TRIAL1 0 0 0 0 0 0 0 severity 0 0 0 0 0 0 0 [[5]] ITEM1 ITEM2 ITEM3 ITEM4 ITEM6 ITEM7 ITEM8 TRIAL1 99 0 0 0 0 0 0 severity 0 0 0 0 0 0 0

除非另有明确说明,否则

所有 MongoDB查询条件“已经”为“AND”条件。因此,除了在$or表达式中“应用”的参数之外,位于$or“外部”的任何内容都被视为“AND”表达式。

因此,$or中的唯一内容是在逻辑细分中适用于“其他用户”的那些条件。否则,在所有情况下,其他所有内容都将作为“AND”应用。

最后你会混淆这些条款。因为当您的结果意味着您希望 ,那么您实际上是指$or