过滤Spring Data mongo query-dsl中的嵌套地图值

时间:2018-12-26 08:16:16

标签: mongodb mongodb-query spring-data spring-data-mongodb querydsl

我正在将Spring-Data-mongo与query-dsl集成在一起,因此我需要为query-dsl查询生成Q文件 这是我的订单POJO:

public class Order {
    private List<Map<String,Object>> items;
}

我的Order.java Q文件

public class QOrder extends EntityPathBase<Order> {

    private static final long serialVersionUID = -682690651L;

    public static final QOrder order = new QOrder("order");

    public final ListPath<java.util.Map<String, Object>, SimplePath<java.util.Map<String, Object>>> items = this.<java.util.Map<String, Object>, SimplePath<java.util.Map<String, Object>>>createList("items", java.util.Map.class, SimplePath.class, PathInits.DIRECT2);

    public QOrder(String variable) {
        super(Order.class, forVariable(variable));
    }

    public QOrder(Path<? extends Order> path) {
        super(path.getType(), path.getMetadata());
    }

    public QOrder(PathMetadata metadata) {
        super(Order.class, metadata);
    }
}

,示例json的顺序为

{
    "items": [{
        "itemName": "phone",
        "quantity": <Integer-Number>
    }
    ]
}

现在,我想从mongo检索所有存在qunatity 1的项目的订单。 现在,我正在生成如下的谓词。 “ QSensorData.sensorData.data.any()。eq( Some-QueryDSL-Expression )”。

我无法确定需要什么方法才能通过eq方法来过滤嵌套地图值。

1 个答案:

答案 0 :(得分:2)

更改订单类以包含List属性,其中Item包含itemName和数量字段。像

public class Order {
    private List<Item> items;
}

public class Item {
    private String itemName;
    private Integer quantity;
}

生成Q类。

使用以下查询返回数量最少为1且数量为1的所有项目。

BooleanExpression expression = QOrder.order.items.any().quantity.eq(1);
List<Order> results = repository.findAll(expression);

如注释中所述,要返回所有值为1的已过滤项目,则必须使用聚合查询。

类似

静态导入

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static org.springframework.data.mongodb.core.aggregation.ArrayOperators.Filter.filter;
import static org.springframework.data.mongodb.core.aggregation.ComparisonOperators.Eq.valueOf;

汇总查询

Aggregation aggregation = newAggregation(
           project().and(filter("items")
             .as("item")
             .by(valueOf(
                  "item.quantity")
                   .equalToValue(
                  1)))
          .as("items");
);

List<Order> results = mongoTemplate.aggregate(aggregation, Order.class, Order.class)