使用$ filter和$ slice对数组子文档进行Spring MongoTemplate查询

时间:2018-06-13 09:11:36

标签: java spring mongodb spring-data-mongodb

我的示例文档是

{
 "projectId":1,
"photoList" : [
        {
            "mobileUrl" : "tempUrl", 
            "category" : "abcd", 
            "selectedByClient" : false
        }, 
        {
            "mobileUrl" : "tempUrl", 
            "category" : "xyz", 
            "selectedByClient" : true
        }, 
         {
            "mobileUrl" : "tempUrl2", 
            "category" : "xyz", 
            "selectedByClient" : true
        }, 
        {
            "mobileUrl" : "tempUrl", 
            "category" : "xyz", 
            "selectedByClient" : false
        }]
}

我的要求是只根据数组子文档元素过滤器获取photoList元素。

e.g。获取photoList,其中selectedByClient = true,category =“xyz”,count = 1.应该返回

{"photoList":[{
            "mobileUrl" : "tempUrl", 
            "category" : "xyz", 
            "selectedByClient" : true
        }]}

我试过下面的代码,但是它会抛出错误

MatchOperation matchStage = Aggregation.match(Criteria.where("projectId").is(id));
        ProjectionOperation projectStage = Aggregation.project().and(new AggregationExpression() {
            @Override
            public DBObject toDbObject(AggregationOperationContext context) {
                DBObject filterExpression = new BasicDBObject();
                filterExpression.put("input", "$photoList");
                filterExpression.put("as", "gallery");
                DBObject categoryCond = null;
                DBObject selectCond = null;
                DBObject cond = null;
                if (!folderName.isEmpty()) {
                    cond = categoryCond = new BasicDBObject("$eq",
                            Arrays.<Object>asList("$$gallery.category", folderName));
                }
                if (selectedByClient) {
                    cond = selectCond = new BasicDBObject("$eq",
                            Arrays.<Object>asList("$$gallery.selectedByClient", true));
                }
                if (categoryCond != null && selectCond != null) {
                    cond = new BasicDBObject("$and", Arrays.<Object>asList(categoryCond, selectCond));
                }
                if (cond == null) {
                    return null;
                }
                filterExpression.put("cond", cond);
                return new BasicDBObject("$filter", filterExpression);
            }
        }).slice(0, 1).as("photoList");
        Aggregation aggregation = Aggregation.newAggregation(matchStage, projectStage);
        AggregationResults<MyClass> groupResults
            = mongoTemplate.aggregate(aggregation,MyClass.class, MyClass.class);

这里我使用过滤器操作与切片不能一起工作。它给出了错误

org.springframework.data.mapping.context.InvalidPersistentPropertyPath: No property 1@67bde17d found on com.xyz.MyClass!
    org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:262)
    org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:235)
    org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:222)
    org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext.getReferenceFor(TypeBasedAggregationOperationContext.java:98)
    org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext.getReference(TypeBasedAggregationOperationContext.java:93)
    org.springframework.data.mongodb.core.aggregation.ProjectionOperation$ProjectionOperationBuilder$OperationProjection.getOperationArguments(ProjectionOperation.java:1411)
    org.springframework.data.mongodb.core.aggregation.ProjectionOperation$ProjectionOperationBuilder$OperationProjection$1.getOperationArguments(ProjectionOperation.java:1479)
    org.springframework.data.mongodb.core.aggregation.ProjectionOperation$ProjectionOperationBuilder$OperationProjection.toDBObject(ProjectionOperation.java:1403)
    org.springframework.data.mongodb.core.aggregation.ProjectionOperation.toDBObject(ProjectionOperation.java:201)
    org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDBObject(AggregationOperationRenderer.java:56)
    org.springframework.data.mongodb.core.aggregation.Aggregation.toDbObject(Aggregation.java:580)
    org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1567)
    org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1502)

如果我不在Aggregation.project()和()方法上使用.slice(0,1),则此代码有效

有没有人知道如何使用spring mongoTemplate使用$ filter和$ slice?

注意:我使用的是spring-data-mongodb 1.10.1.RELEASE

0 个答案:

没有答案