查询在数组中查找ne

时间:2017-06-09 09:23:29

标签: mongodb mongodb-query aggregation-framework

{
    "_id" : ObjectId("593947f95ccc81692670e6b4"),
    "user1" : 100,
    "user2" : 4,
    "messages" : [
        {
            "sender" : 100,
            "datetime" : ISODate("2017-06-08T12:50:01Z"),
            "body" : "hiii 0"
        },
        {
            "sender" : 100,
            "datetime" : ISODate("2017-06-09T12:50:01Z"),
            "body" : "hiii 1"
        },
        {
            "sender" : 4,
            "datetime" : ISODate("2017-06-10T12:50:01Z"),
            "body" : "hiii 2"
        }
    ]
}

我希望找到user1或user2之一为4的所有邮件,并仅列出发件人!= 4的邮件。

寻找输出:

"user1" : 100,
    "user2" : 4,
    "messages" : [
        {
            "sender" : 100,
            "datetime" : ISODate("2017-06-08T12:50:01Z"),
            "body" : "hiii 0"
        },
        {
            "sender" : 100,
            "datetime" : ISODate("2017-06-09T12:50:01Z"),
            "body" : "hiii 1"
        }

试过这个

db.chat.find({ $and:[
 { $or : [ {"user1":4},{"user2":4} ] },
 {"messages.sender": {$ne :4}}
]}).pretty()

但没有工作。

2 个答案:

答案 0 :(得分:1)

您可以使用.aggregate$filter

db.chat.aggregate([
  {
    "$match": {
      "$or": [{"user1": 4}, {"user2": 4}]
    }
  },
  {"$project": {
    "user1" : 1,
    "user2" : 1,
    "messages": {"$filter": {
                      input: "$messages", 
                      as: 'message', 
                      cond: {$ne: ['$$message.sender', 4]}
                }
          }
  }}
])

要仅返回消息计数,您可以使用此

db.chat.aggregate([
  {
    "$match": {
      "$or": [{"user1": 4}, {"user2": 4}]
    }
  },
  {"$project": {
    "user1" : 1,
    "user2" : 1,
    "messageCount": {
      $size: {
        "$filter": {
          input: "$messages",
          as: 'message',
          cond: {$ne: ['$$message.sender', 4]}
        }
      }
    }
  }}
])

或者,如果您想要返回所有messages消息计数,则可以使用此查询

db.chat.aggregate([
  {
    "$match": {
      "$or": [{"user1": 4}, {"user2": 4}]
    }
  },
  {
    "$project": {
      "user1": 1,
      "user2": 1,
      "messages": {
        "$filter": {
          input: "$messages",
          as: 'message',
          cond: {$ne: ['$$message.sender', 4]}
        }
      }
    }
  },
  {
    "$project": {
      user1: 1,
      user2: 1,
      messages: 1,
      messagesCount: { $size: "$messages" }
    }
  }
])

答案 1 :(得分:0)

db.demo.aggregate(

    // Pipeline
    [
        // Stage 1
        {
            $match: {
             $or:[{user1:4},{user2:4}]
            }
        },

        // Stage 2
        {
            $unwind: "$messages"
        },

        // Stage 3
        {
            $match: {
               'messages.sender':{$ne:4}
            }
        },

        // Stage 4
        {
            $group: {
              _id:{_id:'$_id',user1:'$user1',user2:'$user2'},
              messages:{$addToSet:'$messages'}
            }
        },

    ]



);

上面提到的聚合查询在管道

中执行下面提到的聚合阶段
  • $ match运算符匹配user1或者value的文档 user2等于4.

  • $ unwind运算符将messages数组拆分为单独的文档 messages数组中包含的每个值。

  • $ match运算符过滤发件人对象不相等的邮件 到4。

  • $ group operator根据_id字段和值的值对文档进行分组 将消息推送到数组