MongoDB aggregate$elemMatch-在对象数组中搜索变量的ObjectId

MongoDB aggregate$elemMatch-在对象数组中搜索变量的ObjectId,mongodb,aggregate,Mongodb,Aggregate,我一直在尝试搜索由对象组成的数组,这是一个存储在变量中的ObjectId。这是通过$elemMatch实现的,因为我还有几个附加条件 这是一个简化的示例,因此每个人都理解这个问题。 以下是测试数据: { _id: ObjectId('b00000000000000000000101'), friends: [ { friend: ObjectId("b00000000000000000000201"), level:

我一直在尝试搜索由对象组成的数组,这是一个存储在变量中的ObjectId。这是通过$elemMatch实现的,因为我还有几个附加条件

这是一个简化的示例,因此每个人都理解这个问题。 以下是测试数据:

{
    _id: ObjectId('b00000000000000000000101'),
    friends: [
        {
            friend: ObjectId("b00000000000000000000201"),
            level: 5
        },
        {
            friend: ObjectId("b00000000000000000000202"),
            level: 3
        },
        {
            friend: ObjectId("b00000000000000000000203"),
            level: 8
        }
    ]
}
下面是不起作用的查询:

db.test.aggregate([
    {
        $addFields: {
            __testFriend: ObjectId("b00000000000000000000202"),
        },
    },
    {
        $match: {
            friends: {
                $elemMatch: {
                    friend: '$__testFriend',
                    level: { $gte: 3 },
                },
            },
        },
    },
]);
下面是相同的查询,在没有变量的情况下运行,带有硬ObjectId:

db.test.aggregate([
    {
        $addFields: {
            __testFriend: ObjectId("b00000000000000000000202"),
        },
    },
    {
        $match: {
            friends: {
                $elemMatch: {
                    friend: ObjectId("b00000000000000000000202"),
                    level: { $gte: 3 },
                },
            },
        },
    },
]);
有人能告诉我如何使用变量
$\uu testFriend
进行查询吗

谢谢大家!

您可以在$match中使用运算符:

db.test.aggregate([
    {
        $addFields: {
            __testFriend: ObjectId("b00000000000000000000202")
        },
    },
    {
        $match: { $expr: {
            $gt: [ { $size: { $filter: {
                   input: "$friends",
                   as: "one",
                   cond: { $and: [ 
                       { $eq: [ "$$one.friend", "$__testFriend" ] },
                       { $gte: [ "$$one.level", 3 ] }
                   ] }
                } } },
                0
            ] }
        },
    },
]);
您可以在$match中使用运算符:

db.test.aggregate([
    {
        $addFields: {
            __testFriend: ObjectId("b00000000000000000000202")
        },
    },
    {
        $match: { $expr: {
            $gt: [ { $size: { $filter: {
                   input: "$friends",
                   as: "one",
                   cond: { $and: [ 
                       { $eq: [ "$$one.friend", "$__testFriend" ] },
                       { $gte: [ "$$one.level", 3 ] }
                   ] }
                } } },
                0
            ] }
        },
    },
]);

您应该在
$match
阶段之后使用
$addFields
。变量
\uu testFriend
就是一个例子,真正的脚本使用
lookup
之前,它从任何地方检索数据。
$addFields
只是添加了一个最终变量作为测试。您能否通过发布示例文档来解释整个场景幸运的是,不管先前数据的来源如何,都不可能,变量的关注点是相同的。您应该在
$match
阶段之后使用
$addFields
。变量
\uu testFriend
就是一个例子,真正的脚本使用
lookup
之前,它从任何地方检索数据。
$addFields
只是添加了一个最终变量作为测试。您能否通过发布示例文档来解释整个场景幸运的是,无论如何,这是不可能的,不管以前的数据来源如何,变量的问题都是一样的。感谢您的回答,我周末四处看看它是否在我的系统内部工作(因为我想在
$lookup
管道中使用它)。无论如何,这个查询与我的示例非常吻合,谢谢。我觉得很遗憾Mongo没有直接处理变量…谢谢你的回答,我正在周末四处查看它是否在我的系统内部工作(因为我想在
$lookup
管道中使用它)。无论如何,这个查询与我的示例非常吻合,谢谢。我觉得很遗憾Mongo不能直接处理变量。。。