MongoDB查询,使用数组展平对象

时间:2019-05-09 16:12:09

标签: mongodb aggregation-framework

文档:

{
   objectId: 35,
   properties: [
     {
       pset: 'A1',
       property: 'Fire',
       value: '60'
     },
     {
       pset: 'B1',
       property: 'Fire',
       value: '70'
     }  
   ]
}

要查询的输入:

{ 
   psetsWithProperties: [{ pset: 'A1', property: 'Fire'}, { pset: 'abc', property: 'fff'}]
}

pset和property的组合始终是唯一的。因此,属性集合中不能有两个“ A1”和“火”。

预期输出:

[{
  objectId: 35,
  properties: {
    'A1/Fire': '60'
  }
}]

因此第二项(B1,火)不包括在内,因为它不在输入中。

如果根本没有匹配项,则属性对象为空:

[{
  objectId: 35,
  properties: {}
}]

此处应使用MongoDB聚合框架。

我认为$in, $group, $unwind有问题。

真的不知道从哪里开始。

不一定与我的示例完全相同。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

要将一个数组与另一个数组匹配,可以将$filter$anyElementTrue$map结合使用。然后,要动态生成JSON键值,您需要$arrayToObject运算符,请尝试:

db.col.aggregate([
    {
        $project: {
            _id: 0,
            objectId: 1,
            data: {
                $filter: {
                    input: "$properties",
                    as: "docProp",
                    cond: {
                        $anyElementTrue: {
                            $map: {
                                input: [{ pset: 'A1', property: 'Fire'}, { pset: 'abc', property: 'fff'}],
                                as: "paramProp",
                                in: {
                                    $and: [
                                        { $eq: [ "$$docProp.pset", "$$paramProp.pset" ] },
                                        { $eq: [ "$$docProp.property", "$$paramProp.property" ] },
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    {
        $project: {
            objectId: 1,
            properties: {
                $arrayToObject: {
                    $map: {
                        input: "$data",
                        in: {
                            k: { $concat: [ "$$this.pset", "/", "$$this.property" ] },
                            v: "$$this.value"
                        }
                    }
                }
            }
        }
    }
])