搜索MongoDB对象数组,其中属性对于多于1个数组元素具有相同的值

时间:2015-03-14 17:16:28

标签: arrays mongodb spring-data mongodb-query spring-mongo

我有一个Mongo产品系列,其中的Categories字段是一个对象数组。

{
    "_id" : ObjectId("XXX"),
    "title" : "Cool Product",
    "details" : "Some Details",
    "categories" : [ 
        {
            "name" : "Cat1",
            "isPrimary" : true
        }, 
        {
            "isPrimary" : true,
            "name" : "Cat2"
        }, 
        {
            "name" : "Cat3"
        }
    ]
}

因为产品可以有多个类别,所以我想强制主要类别关系(一对一)。但是,在数据迁移中,某些文档的isPrimary属性对于文档中的多个类别为true。我需要在categories数组中的多个数组元素中找到isPrimary为true的产品。这就是我到目前为止所做的:

db.products.find({ "categories" : { "$elemMatch" : { "isPrimary" : { "$exists" : false}}}})

但是这只给出了一个结果,其中isPrimary对于其中一个数组元素不存在。我无法弄清楚如何查询isPrimary在多个数组元素上具有相同的值。此外,这也是一个Spring查询:

Query query = new Query();
query.addCriteria(new Criteria().orOperator(
            Criteria.where("categories").elemMatch(Criteria.where("isPrimary").exists(false)),
            Criteria.where("categories").size(0),
            Criteria.where("categories")
            ));
query.with(new Sort(Sort.Direction.ASC, "title"));
return operations.find(query, Product.class);

1 个答案:

答案 0 :(得分:1)

您需要在此处使用聚合管道:

db.products.aggregate([
 {$unwind:"$categories"},
 {$match:{"categories.isPrimary":true}},
 {$group:{_id:"$_id", numPrimaries:{$sum:1}}},
 {$match:{numPrimaries:{$gt:1}}}
])

这将"放松"类别数组,只保留那些具有isPrimary true," wind"或者通过原始_id对它们进行分组,总结出多少isPrimary值为真,然后过滤掉只有一个的文档。您将留下具有isPrimary true的多个类别的文档的_id值。