为什么MongoDB $ size为空的子数组返回1?

时间:2019-02-11 18:44:11

标签: arrays mongodb

给出以下结构的MongoDB集合

{
"_id" : 1,
"system_id" : "123",
"sub_systems" : [
    {
        "sub_system_id" : "456",
        "status" : "connected",
        "messages_relayed" : [ ] // An array of message_ids that have been relayed
    }
]}

我想创建一个查询,以返回每个子系统已中继多少消息。我从这里开始:

db.messages.aggregate([{
        "$project": {
            "_id": 0,
            "num_of_msgs_relayed": {
                "$cond":
                    {"if": { "$isArray": "$sub_systems.messages_relayed" },
                        "then": { "$size": "$sub_systems.messages_relayed" },
                        "else": 0}
            }}}]);

令我惊讶的是,

  

{“ num_of_msgs_relayed”:1}

问题:我希望查询返回0值,因为基本上我正在投影一个空数组的$ size ! 1背后的原因是什么?

P.S .:以下命令可用于创建显示在 messages 集合上的数据:

  

db.runCommand({         插入:“消息”,         文档:[{'_id':1,'system_id':'123','sub_systems':[{'status':'connected','messages_relayed':[]}]}]}}   )

1 个答案:

答案 0 :(得分:1)

您可以尝试使用以下最简单的查询来观察MongoDB如何解释sub_systems.messages_relayed

db.messages.aggregate([
    { "$project": { "arr": "$sub_systems.messages_relayed"}}
]);

因此,此查询将返回数组数组,因为sub_systems是一个外部数组,而messages_relayed是另一个外部数组。这就是为什么您得到1而不是0

的原因

要“投影空数组的大小”,应在项目之前使用$unwind,低于聚合的结果将返回0而不是1

db.messages.aggregate([
  { $unwind: "$sub_systems" },
  {
    $project: {
      _id: 0,
      num_of_msgs_relayed: {
        $cond: {
          if: { $isArray: "$sub_systems.messages_relayed" },
          then: { $size: "$sub_systems.messages_relayed" },
          else: 0
        }
      }
    }
  }
])