如何选择与内部数组中的值匹配的数组元素

时间:2017-09-18 19:30:32

标签: mongodb aggregation-framework

{
    "_id" : ObjectId("599ec823f896921dbb2855ed"),
    "key1" : "$value",
    "key2" : [
        {
            "Key3" : "$value1"
            "Key4" : "$value2",
            "Key5" : "['v3.1','v3.2','v3.3']",
            "Key6" : "value4",
            "Key7" : "value5",
            "Key8":[
                {"Key9":"value6"},
                {"Key10":"value7"},
                {"Key11":"value8"},
                {"Key12":"value9"},
                {"Key13":"value10"}
            ]
        },
        {
            "Key14" : "$value11"
            "Key15" : "$value12",
            "Key16" : "['v3.11','v3.12','v3.13']",
            "Key17" : "value14",
            "Key18" : "value15",
            "Key19":[
                {"Key20":"value16"},
                {"Key21":"value17"},
                {"Key22":"value18"},
                {"Key23":"value19"},
                {"Key24":"value20"}
            ]
        }
    ]
}

以下查询返回我的空数组,我做错了什么?

db.hotelCol.aggregate([
  {$project:{
    key2:{
      $filter:{
        input:"$key2",
        as:"lock",
        cond:{ $eq:["$$lock.key5","v3.2"]}
      }
    }
  }}
])

我希望得到结果:

{
    "Key3" : $value1"
    "Key4" : "$value2",
    "Key5" : "['v3.1','v3.2','v3.3']",
    "Key6" : "value4",
    "Key7" : "value5",
    "Key8":[
        {"Key9":"value6"},
        {"Key10":"value7"},
        {"Key11":"value8"},
        {"Key12":"value9"},
        {"Key13":"value10"}
    ]
}

1 个答案:

答案 0 :(得分:0)

"key5"属性是"数组"所以$eq作为条件与单个值不匹配。聚合逻辑运算符不像一般查询条件那样自由,也不会尝试匹配每个数组元素。

根据您的可用版本,有不同的运算符。

对于MongoDB 3.4,使用$in

db.hotelCol.aggregate([
  { $project:{
    Key2:{
      $filter:{ 
        input:"$Key2",
        as:"lock",
        cond:{ $in:[ "v3.2", "$$lock.Key5" ] }
      }
    }
  }}
])

对于MongoDB 2.6的版本,请使用$setIsSubset

db.hotelCol.aggregate([
  { $project:{
    Key2:{
      $filter:{ 
        input:"$Key2",
        as:"lock",
        cond:{ $setIsSubset: [ ["v3.2"], "$$lock.Key5" ] }
      }
    }
  }}
])

请注意略有不同的表示法和预期目的。但重点是两者都是为了比较数组"而不是"奇异的价值"。

$in直接将奇异值与数组进行比较。 $setIsSubset运算符比较了两个数组"返回是一个是另一个的子集,意味着它们共享共同的元素作为一个独特的集合"。在后一种情况下,您使用数组包装单个元素以启用比较。

两者都在评估中返回一个布尔条件,这是$filter操作中"cond"的预期条件。

  

另请注意"案例"语句中使用的键。重要的是这些与实际结构相匹配,否则你将不会得到结果,因为关键名称"区分大小写"。