2

オブジェクトの配列である Categories フィールドを持つ Mongo Collection of Products があります。

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

製品には複数のカテゴリがある可能性があるため、プライマリ カテゴリの関係 (1 対 1) を強制したいと考えました。ただし、データ移行では、ドキュメント内の複数のカテゴリに対して isPrimary プロパティが true になっているドキュメントがあります。カテゴリ配列の複数の配列要素で isPrimary が true である製品を見つける必要があります。これは私がこれまでに持っているものです:

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

しかし、これは、配列要素の 1 つに 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);
4

1 に答える 1

1

ここで集約パイプラインを使用する必要があります。

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

これにより、カテゴリの配列が「巻き戻され」、isPrimary が true であるカテゴリのみが「巻き戻され」、元の _id でグループ化されて、isPrimary 値が true であった数が合計され、1 つしかないドキュメントが除外されます。isPrimary が true の複数のカテゴリを持つドキュメントの _id 値が残ります。

于 2015-03-14T21:45:41.733 に答える