MongoDB:Spring数据: - 嵌入式阵列计数

时间:2014-09-11 22:17:36

标签: mongodb spring-data-mongodb

如何识别特定嵌入文档中的元素数量(或)如何查找嵌入数组中的元素数量?

Award
{
    "brand" : [ 
        {
            "name" : "multi",
            "descr" : "Multpple"
        }, 
        {
            "name" : "multi",
            "descr" : "two"
        }, 
        {
            "name" : "multi",
            "descr" : "three"
        }
    ],
    "name" : "Test",
    "narname" : "Nar"
}

For Eg:在上面的文档中,如何使用Spring Data查找嵌入式数组BRAND中的元素数量。?

任何指针都将非常感谢!

1 个答案:

答案 0 :(得分:0)

我不认为有一种方法可以直接得到答案。

您可以使用aggregate来实现它。例如,如果要获取特定文档中数组brand中元素的数量,则应该可以使用这种方式(在mongo shell上运行):

db.Award.aggregate({$match:{_id:id}}, {$unwind:"$brand"}, {$group:{_id:"$_id", count:{$sum:1}}});

count是你想要的结果。

然后使用spring-data-mongodb语法实现它。

-------------- APPENDED ---------------------

// You can find the relative aggregation method from MongoTemplate.java file to handle your requirements.
// For exmaple: 
// public <O> AggregationResults<O> aggregate(Aggregation aggregation, Class<?> inputType, Class<O> outputType)
// The version is around spring-data-mongodb-1.5.0 or higher.

// Below I call the mongo-java-driver directly because I find it needs some time to learn it from spring-data-mongodb. :)

protected int getArraySize(Object id, String collName) {
    // Attention: make sure id is in the correct data type because the following statement would not convert it automatically.

    // Issue codes according to this command line:
    // db.Award.aggregate({$match:{_id:id}}, {$unwind:"$brand"}, {$group:{_id:"$_id", count:{$sum:1}}});

    DBObject match = BasicDBObjectBuilder.start().push("$match").append("_id", id).get();
    DBObject unwind = new BasicDBObject("$unwind", "$brand");
    DBObject group = BasicDBObjectBuilder.start().push("$group").append("_id", "$_id").push("count").append("$sum", 1).get();
    List<DBObject> pipeline = Arrays.asList(match, unwind, group);

    // This aggregate method is supported in higher version of mongo-java-driver, here I use is 2.12.3
    AggregationOutput aggr = this.mongoTemplate.getCollection(collName).aggregate(pipeline);
    for (DBObject dbo : aggr.results()) {
        Object count = dbo.get("count");
        if (count instanceof Number) {
            return ((Number)count).intValue();
        }
    }
    return 0;
}