当前位置: 首页 > 知识库问答 >
问题:

Spring数据MongoDb从字符串到ObjectId的聚合查找

江飞章
2023-03-14

我在mongodb 4.0中使用Spring(boot)数据2.2.7。我已经设置了3个集合,试图通过聚合查找操作加入这些集合。

  • 目录
  • 股票
  • 操作

目录

{
    "_id" : ObjectId("5ec7856eb9eb171b72f721af"),
    "model" : "HX711",
    "type" : "DIGITAL",
....
}

映射由

@Document(collection = "catalog")
public class Product implements Serializable {

    @Id
    private String _id;
    @TextIndexed
    private String model;
....

股票

{
    "_id" : ObjectId("5ec78573b9eb171b72f721ba"),
    "serialNumber" : "7af646bb-a5a8-4b86-b56b-07c12a625265",
    "bareCode" : "72193.67751691974",
    "productId" : "5ec7856eb9eb171b72f721af",
......
}

映射由

@Document(collection = "stock")
public class Component implements Serializable {

    @Id
    private String _id;
    private String productId;
....

productId字段引用目录集合中的_id字段

操作

{
    "_id" : ObjectId("5ec78671b9eb171b72f721d3"),
    "componentId" : ""5ec78573b9eb171b72f721ba",
    .....

}

映射由

public class Node implements Serializable {

    @Id
    private String _id;
    private String componentId;
....

组件ID字段指的是库存集合中的_id

我想查询操作或库存收集,以检索相应的节点或组件对象列表,该列表由Product.model字段(在目录集合中)排序。)

虽然目标是在Java编码,但我试图在Mongo shell中首先发出请求,但我甚至无法让它工作,因为我试图用ObjectId连接(查找)一个html" target="_blank">字符串: Node.componentId-

对于关系组件(股票)-

LookupOperation lookupOperation = LookupOperation.newLookup()
        .from("catalog")
        .localField("productId")
        .foreignField("_id")
        .as("product");

TypedAggregation<Component> agg =
        Aggregation.newAggregation(
                Component.class,
                lookupOperation
        );


AggregationResults<Component> results = mongoTemplate.aggregate(agg, "stock", Component.class);
return results.getMappedResults();

但它返回整个组件记录没有产品信息。

[{"_id":"5ec78573b9eb171b72f721b0","uuId":"da8800d0-b0af-4886-80d1-c384596d2261","serialNumber":"706d93ef-abf5-4f08-9cbd-e7be0af1681c","bareCode":"90168.94737714577","productId":"5ec7856eb9eb171b72f721a9","created":"2020-05-22T07:55:31.66","updated":null}, .....]

谢谢你的帮助。

注意:除了@Valijon答案能够得到预期的结果返回的对象必须包括一个产品属性要么什么都不返回(使用JSON REST服务例如)

public class ComponentExpanded implements Serializable {

    private String product;
....

具有

AggregationResults<ComponentExpanded> results =
        mongoTemplate.aggregate(agg,mongoTemplate.getCollectionName(Component.class), ComponentExpanded.class);

共有1个答案

何承
2023-03-14

正如您所观察到的,问题在于productId\u id之间的类型不匹配。

为了连接这些数据,我们需要执行不相关的子查询,并且不是每个“新”功能都能立即将其放入抽象层,例如springmongo

试试这个:

Aggregation agg = Aggregation.newAggregation(l -> new Document("$lookup",
    new Document("from", mongoTemplate.getCollectionName(Product.class))
        .append("let", new Document("productId", new Document("$toObjectId", "$productId")))
        .append("pipeline",
                Arrays.asList(new Document("$match",
                        new Document("$expr",
                                new Document("$eq", Arrays.asList("$_id", "$$productId"))))))
        .append("as", "product")),
    Aggregation.unwind("product", Boolean.TRUE));

AggregationResults<Component> results = mongoTemplate.aggregate(agg, 
    mongoTemplate.getCollectionName(Component.class), Component.class);
return results.getMappedResults();

在这里查看shell查询的样子。

注意:对于Javav1。7,您需要实现如下的聚合操作

AggregationOperation l = new AggregationOperation() {

    @Override
    public Document toDocument(AggregationOperationContext context) {
        return new Document(...); // put here $lookup stage
    }

};
 类似资料:
  • --------编辑-------------------------------------------- 我在我的服务器行为中发现了一些非常奇怪的东西。当我执行一个简单的findById调用时,我的image项是一个Objectid数组。但是当使用聚合时,ObjecIds变成了String。有人知道上面是什么吗?

  • 有人能帮我把这个mongoDB聚合转换成Spring数据mongo吗? 我试图在每个邀请函文件中获得未提醒与会者的电子邮件列表。 让它在mongo shell中运行,但需要在Spring data mongo中运行。 我的shell查询 ) 正如你们所看到的,这是我提出的,它在管道的项目和团队运作中并没有像预期的那样发挥作用。下面给出了生成的查询。 聚合对象创建 它创建以下查询 聚合对象生成的查询

  • 假设我有一个用户类,它有一个对客户文档的手动引用: 两个身份我都要 保存用户文档时,“id”将转换为ObjectId,但是customerId将保存为字符串。我可以使用ObjectId类型的customerId,但我更希望将POJO作为字符串,并在保存/查询时将customerId自动转换为ObjectId。似乎没有任何行为类似于@Id的内置注释,但可以用于手动引用。我将如何着手创建一个,或者有更

  • 我有以下收藏: 我试图将电影(及其所有细节)与用户状态和对该电影的感觉相匹配,并使用聚合: 其中返回: 我希望的结果是匹配user_status中的第一部电影,以获得最终结果: 我想我的下一步是: 但是它不起作用——不确定这个$addFields是否正确,我知道的一个问题是,我的第一个_id是一个ObjectId,第二个似乎是一个字符串。

  • 标题可能不太清楚,问题在这里 我正在执行此表单中的更新: 仅当没有具有相同用户ID的文档时才在数组中插入文档(解决方法是,唯一索引在数组中不起作用)。代码在mongo控制台上运行良好。从我的应用程序中,我使用以下内容: 如果作为“userid”,我使用的字符串不能是mongo ObjectId,那么这很好,但是如果我在示例中使用该字符串,则执行的查询如下所示(来自mongosniff): 该字符串

  • 我使用Spring(引导)2.2.7与mongoDB 4.0运行在Debian Stretch(9.12)。我已经设置了3个集合,我试图通过聚合查找级联操作加入这些集合。 操作(节点类) 股票(组件类) 目录(产品类) 每个类都有一个将它们链接在一起的uuid字符串属性。 节点(传感器、接收器、基站等) 组件(带有序列号、条形码的交付产品…) 产品(市场人工制品) 在mongo shell中运行此