我有一个像
这样的集合 {
"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
。
如何进行此类复杂查询?
答案 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
}