首页 > 解决方案 > 使用 $filter 和 $slice 对数组子文档进行 Spring MongoTemplate 查询

问题描述

我的示例文件是

{
 "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 元素。

例如,在 selectedByClient = true 和 category = "xyz" 和 count = 1 的地方获取 photoList。它应该返回

{"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().and() 方法上使用 .slice(0, 1) ,则此代码有效

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

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

标签: javaspringmongodbspring-data-mongodb

解决方案


推荐阅读