关于Mongodb.Aggregate变量

时间:2016-11-30 09:34:49

标签: mongodb

这是我的文件:

members: [
    {
        _id: 'id1'
        name: 'Jack',
        group: 0
    },
    {
        _id: 'id2'
        name: 'Rose',
        group: 0
    },
    {
        _id: 'id3'
        name: 'Tom',
        group: 1
    }
]

我想通过memberId搜索某个人的所有成员以及所有成员的总数。

例如,当我输入id1时,它将返回:

{
  count: 3,
  members: [
    {
      _id: 'id1',
      name: 'Jack'
    },
    {
      _id: 'id2',
      name: 'Rose'
    }
  ]
} 

当我输入id3时,它将返回:

{
  count: 3,
  members: [
    {
      _id: 'id3',
      name: 'Tom'
    }
  ]
}

我试图这样做:

db.collectionName.aggregate({
  $project: {
    count: {$size: '$members'},
    members: 1
  }
}, 
{
  $unwind: '$members'
},
{
  $project: {
    count: 1,
    members: {
      $cond: [{$eq: ['$members._id', TheInputMemberId]}, '$member', null]
    }
  }
})

但是,过滤器只包含_id而不是_idgroup,因此结果始终只有一个成员。

我不知道如何首先获取组变量,然后进行过滤。

期待您的回复!谢谢!

1 个答案:

答案 0 :(得分:1)

你可以尝试这样的事情。添加了项目和组阶段,以便在传递了id的任何结果元素匹配时保留数据结果。

$map 在每个数据结果元素中应用传递的id和id之间的等于比较,并生成具有true和false值的数组。 $anyElementTrue 检查此数组,仅当数组中至少有一个true值时才返回true。匹配阶段仅包含匹配值为true的元素。

aggregate({
  "$project": {
    "count": {
      "$size": "$members"
    },
    "members": 1
  }
}, {
  "$unwind": "$members"
}, {
  "$group": {
    "_id": "$members.group",
    "data": {
      "$push": {
        "name": "$members.name",
        "_id": "$members._id"
      }
    },
    "count": {
      "$first": "$count"
    }
  }
}, {
  "$project": {
    "_id": 1,
    "data": 1,
    "matched": {
      "$anyElementTrue": {
        "$map": {
          "input": "$data",
          "as": "result",
          "in": {
            "$eq": ['$$result._id', 'id1']
          }
        }
      }
    }
  }
}, {
  "$match": {
    "matched": true
  }
}).pretty()

替代版本:

与上述版本类似,但这个版本将项目和匹配阶段合二为一。 $cond $redact 帐户匹配,当找到匹配时,它会保持匹配完整的树或丢弃它。

aggregate({
    "$project": {
        "count": {
            "$size": "$members"
        },
        "members": 1
    }
}, {
    "$unwind": "$members"
}, {
    "$group": {
        "_id": "$members.group",
        "data": {
            "$push": {
                "name": "$members.name",
                "_id": "$members._id"
            }
        },
        "count": {
            "$first": "$count"
        }
    }
}, {
    "$redact": {
        "$cond": [{
                "$anyElementTrue": {
                    "$map": {
                        "input": "$data",
                        "as": "result",
                        "in": {
                            "$eq": ['$$result._id', 'id1']
                        }
                    }
                }
            },
            "$$KEEP",
            "$$PRUNE"
        ]
    }
}).pretty()