如何在MongoDB $投影管道中的array.indexOf中使用变量名

时间:2015-04-13 02:52:43

标签: mongodb mongoose mongodb-query

我有一个像

这样的集合
   {
        "LifeTime" : 123.000,
        "Host" : "xxx.com",
    }, 
    {
        "LifeTime" : 213.000,
        "Host" : "yyy.com",
    }, 
    {
        "LifeTime" : 321.000,
        "Host" : "zzz.com",

    } 

和预定义的数组,如

["xxx.com","yyy.com"]

现在我想使用$let& $cond,如果数组中存在Host,那么LifeTime将为0,否则与LifeTime相同。

我试过这个

LifeTime: {
    $let: {
    vars: {
        hostname: '$Host'
    },
    in: {
        "$cond": [
            {
                "$and": [
                    {
                        "$gte": [
                            ArrayOfPredefinedHost.indexOf('$$hostname'),
                            0
                        ]
                    }
                ]
            },
            0,
            "$LifeTime"
        ]
    }
    }
}

但它没有返回预期的结果。我认为indexOf正试图找到$$hostname而不是xxx.com,yyy.com & zzz.com

如何进行此类复杂查询?

1 个答案:

答案 0 :(得分:1)

以下聚合管道将首先对文档进行分组,以允许使用$addToSet累加器运算符包含单个主机元素的其他数组字段。然后,此附加字段将用于 $project 表达式中的下一个 $cond 管道阶段,利用$setIsSubset运算符:

var ArrayOfPredefinedHost = ["xxx.com", "yyy.com"];
db.collection.aggregate([
    {
        "$group": {
            "_id": {
                "id": "$_id",
                "LifeTime": "$LifeTime",
                "Host": "$Host"
            },
            "HostSet": { "$addToSet": "$Host" }
        }
    },
    {
        "$project": {
            "_id": 0,
            "LifeTime": {
                "$cond": [ { "$setIsSubset": [ "$HostSet", ArrayOfPredefinedHost ] }, "$_id.LifeTime", 0]
            },
            "Host": "$_id.Host"
        }
    }
]);

<强>输出

/* 0 */
{
    "result" : [ 
        {
            "LifeTime" : 0,
            "Host" : "zzz.com"
        }, 
        {
            "LifeTime" : 213,
            "Host" : "yyy.com"
        }, 
        {
            "LifeTime" : 123,
            "Host" : "xxx.com"
        }
    ],
    "ok" : 1
}