将数组中的元素字段与MongoDB中的字段进行比较

时间:2016-11-14 03:42:45

标签: arrays mongodb

我有一个像这样的收藏集团:

{
    "_id" : ObjectId("5822dd5cb6a69ca404e0d93c"),
    "name" : "GROUP 1",
    "member": [
        {
            "_id": ObjectId("5822dd5cb6a69ca404e0d93d")
            "user": ObjectId("573ac820eb3ed3ea156905f6"),
            "task": ObjectId("5822ddecb6a69ca404e0d942"),
        },
        {
            "_id": ObjectId("5822dd5cb6a69ca404e0d93f")
            "user": ObjectId("57762fce5ece6a5d04457bf9"),
            "task": ObjectId("5822ddecb6a69ca404e0d943"),
        }
    ],
    curTask: {
        "_id": ObjectId("5822ddecb6a69ca404e0d942"),
        "time": ISODate("2016-01-01T01:01:01.000Z")
    }
}
{
    "_id" : ObjectId("573d5ff8d1b7b3b32e165599"),
    "name" : "GROUP 2",
    "member": [
        {
            "_id": ObjectId("574802e031e70b503eabe195")
            "user": ObjectId("573ac820eb3ed3ea156905f6"),
            "task": ObjectId("5775f1a74b41037e246a51d1"),
        },
        {
            "_id": ObjectId("574802e031e70b503eabe198")
            "user": ObjectId("573ac79beb3ed3ea156905f4"),
            "task": ObjectId("576cfa042c0a4054794dd242"),
        }
    ],
    curTask: {
        "_id": ObjectId("577249a2f9dba0c750ef705b"),
        "time": ISODate("2016-01-01T01:01:01.000Z")
    }
}
{
    "_id" : ObjectId("574802e031e70b503eabe194"),
    "name" : "GROUP 3",
    "member": [
        {
            "_id": ObjectId("574be0a2bf16234f5a752f83")
            "user": ObjectId("573ac79beb3ed3ea156905f4"),
            "task": ObjectId("5822ddecb6a69ca404e0d942"),
        },
        {
            "_id": ObjectId("574d397d6e9f07d64d1e4e40")
            "user": ObjectId("57762fce5ece6a5d04457bf9"),
            "task": ObjectId("5822ddecb6a69ca404e0d943"),
        }
    ],
    curTask: {
        "_id": ObjectId("5822ddecb6a69ca404e0d942"),
        "time": ISODate("2016-01-01T01:01:01.000Z")
    }
}

我希望能够找到所有使用objectId 573ac820eb3ed3ea156905f6(第1组中的第一个用户)的用户不执行与currentTask相同的任务的组。到目前为止,我已经写了这个查询:

db.getCollection('groups').find({"member":{ "$elemMatch": {"user": ObjectId("573ac820eb3ed3ea156905f6")
, "task": { "$ne":"this.curTask._id"}}}})

但这似乎不起作用,因为它仍然返回用户573ac820eb3ed3ea156905f6拥有task === curTask._id的群组。 elemMatch的前半部分似乎工作正常(只在成员中查找具有objectid 573ac820eb3ed3ea156905f6的用户的组,查询仅返回组1和2,因为组3没有该用户。)但我似乎无法做出mongodb将数组对象中的字段与文档的另一个字段进行比较。任何人都知道如何进行这种比较?

1 个答案:

答案 0 :(得分:1)

这个问题有两个解决方案 -

首先 - 使用$where。通过使用$where,您可以在mongodb查询中使用Javascript代码。使代码变得灵活,但缺点是它运行缓慢,因为Javascript代码必须运行而不是更优化的mongoDB C ++代码。

db.getCollection('groups').find({
    $where: function () {
            var flag = 0;

            for(var i=0; i<obj.member.length;i++) {
                    if(obj.member[i].user.str == ObjectId("573ac820eb3ed3ea156905f6").str && obj.member[i].task.str != obj.curTask._id.str ){flag = 1; break;}
                }
            return flag;
        }
    })

第二 - 使用聚合管道。在这里,我将展开数组,按照描述进行匹配,最后根据需要重新创建数组。如果不需要member数组中不匹配的元素,可以省略最后一个分组部分。

[
{$match: {'member.user': ObjectId("573ac820eb3ed3ea156905f6")}},
{$unwind: '$member'},
{$project: {
    name: 1,
    member: 1,
    curTask: 1,
    ne: {$and: [{$ne: ['$member.task', '$curTask._id']}, {$eq: ['$member.user', ObjectId("573ac820eb3ed3ea156905f6")]}]}
    }},
{$group: {
    _id: '$_id',
    member: {$push: '$member'},
    curTask: {$first: '$curTask'},
    name: {$first: '$name'},
    check: {$sum: {$cond: ['$ne', 1, 0]}}
    }},
{$match: {check: {$gt: 0}}}
]