【问题标题】:Comparing an element's field in array with a field in MongoDB将数组中的元素字段与 MongoDB 中的字段进行比较
【发布时间】:2016-11-14 14:03:57
【问题描述】:

我有一个这样的收藏组:

{
    "_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 比较数组对象中的一个字段与文档的另一个字段。有人知道我该如何进行比较吗?

【问题讨论】:

  • 发布转储数据
  • 不知道如何使用这个内部元素匹配器
  • 你是否关心数组中符合第一个条件的其他成员的任务。
  • @hyades 我真的不这样做,但这会改变什么吗?

标签: arrays mongodb


【解决方案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}}}
]

【讨论】:

  • 非常感谢您的回答。我什至不知道您可以在查询中使用 js 代码。第一种方式对我来说非常有效(我只需要将.str 更改为+ '' ,这样它也将涵盖用户没有任何任务分配给他的情况,因此他的任务是null)。
猜你喜欢
  • 1970-01-01
  • 2019-07-16
  • 1970-01-01
  • 2021-05-19
  • 1970-01-01
  • 1970-01-01
  • 2017-07-08
  • 2022-10-01
  • 1970-01-01
相关资源
最近更新 更多