【问题标题】:Filter over Nested Map value's in Spring data mongo query-dsl过滤 Spring 数据 mongo query-dsl 中的嵌套映射值
【发布时间】:2019-05-24 13:17:59
【问题描述】:

我正在将 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 中检索所有订单,其中任何项目都存在数量为 1。 现在我正在生成我的谓词,如下所示。 “QSensorData.sensorData.data.any().eq(Some-QueryDSL-Expression)”。

我无法确定需要在 eq 方法中传递什么来过滤嵌套映射值。

【问题讨论】:

  • 据我了解查询 dsl 以使用类型安全 api 查询域类型。所以使用Map数据类型查询不是正确的方法,你可以直接使用Document使用mongo java驱动。因此,如果您可以更新 Order pojo 以包含所有字段,然后您可以生成 Q 类并使用类型安全的方式来查询 mongodb。
  • @veeram 我提供了由上面的 querydsl 插件生成的 Q 类,请检查并告诉我有什么问题
  • 数据类型Map的选择不正确。您可以更改 Order pojo 以包含项目名称、数量等字段而不是 List 吗?什么是预期输出?您是否希望根据数量过滤项目?如果是,则不能使用 dsl 查询,因为它需要聚合查询。

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


【解决方案1】:

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

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

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

生成 Q 类。

使用下面的查询返回至少有一个数量为 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)

【讨论】:

  • 如果使用 pojo 键会受到限制,所以我试图避免这种情况。
  • 抱歉,无法使用查询 dsl 直接查询地图。 Query dsl 提供需要密钥的类型安全查询。喜欢使用 Map 的可以直接使用 mongo java 驱动。
  • 投反对票时请提供评论
猜你喜欢
  • 2021-08-26
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 2020-04-18
  • 1970-01-01
  • 2021-08-13
  • 1970-01-01
相关资源
最近更新 更多