在mongodb中查找嵌入式子文档中的重复键

时间:2015-03-27 20:10:56

标签: mongodb mongodb-query

我正在尝试创建一个查询,允许我在MongoDB中的子文档中找到重复键。

它需要能够查询任意数量的文档,并在子文档中查看它们之间的重复键。我的子文档的密钥称为attributes,我需要能够定位特定的文档查询并提取它们共享的重复属性键。

修改 我忘了提到我提前不知道属性的名称。我需要能够基本上选择他们共享的不同属性并聚合这些值。

收集样本:

[
    {
        sku: '123',
        attributes: {
            size: 'L',
            custom: 7
        }
    },
    {
        sku: '456',
        attributes: {
            size: 'M'
        }
    },
    {
        sku: 'abc',
        attributes: {
            material: 'cotton'
            size: 'S'
        }
    }
]

期望的结果(如果可能):

{
   size: [' S', 'M', 'L']
}

如果无法获得所需的结果,我至少希望能够回来[ 'size' ]

这个过程需要尽可能地进行优化,我似乎无法得到一个恰好返回我需要的查询,非常感谢任何帮助=)

这是我到目前为止所拥有的

db.getCollection('myCollection').aggregate([
    { $match: {
            _id: { $in: [ObjectId("55158b0bd6076278295cf022"), ObjectId("55158b0bd6076278295cf021"), ObjectId("55158b0bd6076278295cf01f")   ] }
        }
    },
    { $project: { attributes: 1 }},
    { $group: { _id: '$attributes' } }

])

此输出的产品:

{
    "result" : [ 
        {
            "_id" : {
                "shirt_size" : "S",
                "shirt_color" : "Blue",
                "custom_attr" : "adsfasdf"
            }
        }, 
        {
            "_id" : {
                "shirt_size" : "M",
                "shirt_color" : "Green"
            }
        }, 
        {
            "_id" : {
                "shirt_size" : "L",
                "shirt_color" : "Red"
            }
        }
    ],
    "ok" : 1.0000000000000000,
    "$gleStats" : {
        "lastOpTime" : Timestamp(1427475045, 1),
        "electionId" : ObjectId("54f7c1edf8e5ff44cec194b6")
    }
}

我觉得它很接近,我只是错过了最后一步:(

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

$addToSet(aggregation)会返回一组唯一值 - http://docs.mongodb.org/manual/reference/operator/aggregation/addToSet/

使用以下聚合(获取每个Doc的唯一大小):

db.coll1.aggregate([
{$unwind : "$testdoc"}, 
{$group : {_id: "$_id", size: {$addToSet: "$testdoc.attributes.size"}}}
])

给出以下结果:

{
"result" : [
    {
        "_id" : ObjectId("551621fe6155a7741a0d328a"),
        "size" : [
            "M",
            "L"
        ]
    },
    {
        "_id" : ObjectId("551621fe6155a7741a0d328b"),
        "size" : [
            "L"
        ]
    },
    {
        "_id" : ObjectId("551621fe6155a7741a0d3289"),
        "size" : [
            "S",
            "M",
            "L"
        ]
    }
],
"ok" : 1
}

以下聚合在所有文档中返回唯一大小:

db.coll1.aggregate([ 
    {$unwind : "$testdoc"}, 
    {$group : 
         {_id: "AllSizes", size: {$addToSet: "$testdoc.attributes.size"}}} ])

结果:

{
"result" : [
    {
        "_id" : "AllSizes",
        "size" : [
            "S",
            "M",
            "L"
        ]
    }
],
"ok" : 1
}

基于以下文档:

> db.coll1.find().pretty()
{
"_id" : ObjectId("551621fe6155a7741a0d3289"),
"testdoc" : [
    {
        "sku" : "123",
        "attributes" : {
            "size" : "L",
            "custom" : 7
        }
    },
    {
        "sku" : "456",
        "attributes" : {
            "size" : "M"
        }
    },
    {
        "sku" : "abc",
        "attributes" : {
            "material" : "cotton",
            "size" : "S"
        }
    }
]
}
{
"_id" : ObjectId("551621fe6155a7741a0d328a"),
"testdoc" : [
    {
        "sku" : "123",
        "attributes" : {
            "size" : "L",
            "custom" : 7
        }
    },
    {
        "sku" : "456",
        "attributes" : {
            "size" : "M"
        }
    },
    {
        "sku" : "abc",
        "attributes" : {
            "material" : "cotton",
            "size" : "M"
        }
    }
]
}
{
"_id" : ObjectId("551621fe6155a7741a0d328b"),
"testdoc" : [
    {
        "sku" : "123",
        "attributes" : {
            "size" : "L",
            "custom" : 7
        }
    },
    {
        "sku" : "456",
        "attributes" : {
            "size" : "L"
        }
    },
    {
        "sku" : "abc",
        "attributes" : {
            "material" : "cotton",
            "size" : "L"
        }
    }
]
}