Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果对象数组[MongoDB]中存在值,则计数_Mongodb - Fatal编程技术网

如果对象数组[MongoDB]中存在值,则计数

如果对象数组[MongoDB]中存在值,则计数,mongodb,Mongodb,我正在用MongoDB开发一个简单的聊天应用程序,结果陷入了困境 我在数据库中的文档如下所示 { "_id" : ObjectId("605a217ed8168f4c262f4782"), "message" : "Hi, This is a test message", "created" : ISODate("2021-03-23T17:12:30.000Z")

我正在用MongoDB开发一个简单的聊天应用程序,结果陷入了困境

我在数据库中的文档如下所示

{
  "_id" : ObjectId("605a217ed8168f4c262f4782"),
  "message" : "Hi, This is a test message",
  "created" : ISODate("2021-03-23T17:12:30.000Z"),
  "user" : {
    "_id" : ObjectId("5977af7df1d8cc4623283b14"),
    "name" : "Sender Of Message"
  },
  "recipients" : [ 
    {
      "_id" : ObjectId("5977af7df1d8cc4623283b14"),
      "time" : ISODate("2021-03-23T17:12:30.000Z")
    }, 
    {
      "_id" : ObjectId("5df50a5eaa0e3c3104006101"),
      "time" : ISODate("2021-03-23T17:12:35.000Z")
    }
  ],
  "target" : {
    "_id" : ObjectId("5df50a5eaa0e3c3104006101"),
    "name" : "Target Person"
  },
  "status" : 1
}
当我试图获取最后一条带有用户未读计数的消息时,我总是得到1

这是我试过的问题

db.collection.aggregate([
  { $match: { 'target._id': ObjectId('5df50a5eaa0e3c3104006101'), status: 1 } },
  { $sort: { _id: -1 } },
  {
    $group: {
      _id: '$user._id',
      doc: { $first: '$$ROOT' },
      unread: {
        $sum: {
          $cond: {
            if: { $ne: [ ObjectId('5df50a5eaa0e3c3104006101'), '$recipients._id' ] },
            then: 1,
            else: 0
          }
        }
      }
    }
  }
])
如果集合甚至只包含上面的一个文档,那么它应该将0作为
recipients
数组中的对象,该数组已经包含
\u id
作为
ObjectId('5df50a5eaa0e3c3104006101')
,但未读计数得到1。有什么帮助吗

这是我从查询中得到的输出

{
  "_id" : ObjectId("5977af7df1d8cc4623283b14"),
  "doc" : {
    "_id" : ObjectId("605a217ed8168f4c262f4782"),
    "message" : "Hi, This is a test message",
    "created" : ISODate("2021-03-23T17:12:30.000Z"),
    "user" : {
      "_id" : ObjectId("5977af7df1d8cc4623283b14"),
      "name" : "Sender Of Message"
    },
    "recipients" : [ 
      {
        "_id" : ObjectId("5977af7df1d8cc4623283b14"),
        "time" : ISODate("2021-03-23T17:12:30.000Z")
      }, 
      {
        "_id" : ObjectId("5df50a5eaa0e3c3104006101"),
        "time" : ISODate("2021-03-23T17:12:35.000Z")
      }
    ],
    "target" : {
      "_id" : ObjectId("5df50a5eaa0e3c3104006101"),
      "name" : "Target Person"
    },
    "status" : 1
  },
  "unread" : 1.0
}
我知道它为什么显示为计数为
1

数组
recipients
包含一个对象,其中
\u id
ObjectId(“5977af7df1d8cc4623283b14”)
,因此它是一个不匹配的条件。这导致满足if条件并产生值
1

但我需要弄清楚如何查询它以获得实际值

请注意,我不能在
recipients
数组上使用
$push
运算符,因为它可能有更多的对象(可能在将来)

请尝试这样使用:

   db.getCollection('test').aggregate([
    { $match: { 'target._id': ObjectId('5df50a5eaa0e3c3104006101'), status: 1 
     } },
     { $sort: { _id: -1 } },
      { $unwind: { path: "$recipients", preserveNullAndEmptyArrays: true } },
       {
         $group: {
           _id: '$user._id',
           doc: { $first: '$$ROOT' },
           unread: {
              $sum: {
                $cond: {
                  if: { $ne: ['$recipients._id', 
                   ObjectId('5df50a5eaa0e3c3104006101') ] },
                   then: 1,
                   else: 0
                  }
                }
               }
              }
             } 
           ])

谢谢你的支持,但我自己找到了答案。 以下是我根据要求获取数据的方法

我所做的不是在数组中搜索记录,而是

  • 将数据数组过滤到我不需要的
    \u id
    ,因此数组将只有一个文档,否则它将为空
  • 当接受条件的否定时。也就是说,当数组中有一个值时,我需要计数器为0,否则它应该为1
  • 因此,我使用检查数组的大小并过滤掉其他
    \u id
    s,然后根据需要增加计数器

  • 它仍然给我
    1
    作为输出。正如我所说,它与
    ObjectId(“5977af7df1d8cc4623283b14”)
    匹配,因为它不等于
    ObjectId('5df50a5eaa0e3c3104006101')
    ,同样根据文档,它没有指定操作符的位置和值。它只声明为
    {$ne:[,]}
    尝试使用上述查询它有一个错误
    “无法识别的表达式'$nor'
    我没有使用您在这里应用的逻辑,但问题是数组
    收件人将有两个以上的对象,正如我已经提到的
    它可能有更多的对象(可能在将来)
    。在这种情况下,这种逻辑将失败
    db.collection.aggregate([
        { $match: { 'target._id': ObjectId('5df50a5eaa0e3c3104006101'), status: 1 } },
        { $sort: { _id: -1 } },
        {
            $group: {
                _id: '$user._id',
                doc: { $first: '$$ROOT' },
                unread: {
                    $sum: {
                        $cond:{
                            if: {
                                $size: {
                                    $filter: {
                                        input: '$recipients',
                                        as: 'item',
                                        cond: { $eq: [ ObjectId('5df50a5eaa0e3c3104006101'), '$$item._id' ] }
                                    }
                                }
                            },
                            then: 0,
                            else: 1
                        }
                    }
                }
            }
        }
    ])