我使用Spring(引导)2.2.7与mongoDB 4.0运行在Debian Stretch(9.12)。我已经设置了3个集合,我试图通过聚合查找级联操作加入这些集合。
每个类都有一个将它们链接在一起的uuid字符串属性。
节点(传感器、接收器、基站等)
@Document(collection = "operations")
public class Node implements Serializable {
@Id
private String _id;
private String componentUuId;
....
}
组件(带有序列号、条形码的交付产品…)
@Document(collection = "stock")
public class Component implements Serializable {
@Id
private String _id;
private String uuId;
private String productUuId;
....
}
产品(市场人工制品)
@Document(collection = "catalog")
public class Product implements Serializable {
@Id
private String _id;
private String uuId;
....
}
在mongo shell中运行此命令时:
db.operations.aggregate([
{
$lookup: {
"from": "stock",
"localField": "componentUuId",
"foreignField": "uuId",
"as": "component"
}
},
{
$lookup: {
"from": "catalog",
"localField": "component.productUuId",
"foreignField": "uuId",
"as": "product"
}
}
]).pretty()
我明白了
{
"_id" : ObjectId("5ec952a7714e7e248b5fb98b"),
"uuId" : "3b5e3417-166c-4d69-9fa5-b0856d819541",
"componentUuId" : "57eff5c5-8b3c-43cb-9f2d-1c4098fc0c1f",
"component" : [
{
"_id" : ObjectId("5ec952a4714e7e248b5fb97f"),
"uuId" : "57eff5c5-8b3c-43cb-9f2d-1c4098fc0c1f",
"productUuId" : "3da7a6a6-ccf6-4fe1-892a-a6d6b82396c1",
"created" : ISODate("2020-05-23T14:43:16.588Z"),
"_class" : "org.open_si.udc_common.models.Component"
.......
}
],
"product" : [
{
"_id" : ObjectId("5ec952a1714e7e248b5fb969"),
"uuId" : "3da7a6a6-ccf6-4fe1-892a-a6d6b82396c1",
"model" : "TMP36GT9Z",
"_class" : "org.open_si.udc_common.models.Product"
......
}
]
}
因此,为了在Java中实现同样的目标,我运行了
Aggregation agg = Aggregation.newAggregation(
Aggregation.lookup(mongoTemplate.getCollectionName(Component.class),
"componentUuId", "uuId", "component"),
Aggregation.lookup(mongoTemplate.getCollectionName(Product.class),
"component.productUuId", "uuId", "product")
);
AggregationResults<NodeExpanded> results = mongoTemplate.aggregate(agg, mongoTemplate.getCollectionName(Node.class), NodeExpanded.class);
return results.getMappedResults();
使用NodeExpanded类
public class NodeExpanded implements Serializable {
private String uuId;
private Component component;
private Product product;
....
}
注意:我没有扩展Node基类,因为在下面的问题之前我得到了一个重复的密钥错误。
问题是,我在托管该代码的服务中遇到了一个错误:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
不幸的是,我不知道如何在Spring的较低级别进行调试,也无法找出最初的错误是什么。
请注意,让产品链接到组件的代码如下:
Aggregation agg = Aggregation.newAggregation(
Aggregation.lookup(mongoTemplate.getCollectionName(Product.class),
"productUuId", "uuId", "product")
);
AggregationResults<ComponentExpanded> results =
mongoTemplate.aggregate(agg,mongoTemplate.getCollectionName(Component.class), ComponentExpanded.class);
return results.getMappedResults();
随着扩展类:
public class ComponentExpanded implements Serializable {
private String uuId;
private Product product;
...
}
有什么想法吗?提前谢谢。
编辑
为了更深入地调试,我限制了代码只能将操作集合(Node.class)连接到库存(Component.class),就像我对库存(Component.class)和目录(Product.class)工作正常。
public List<NodeExpanded> list() {
Aggregation agg = Aggregation.newAggregation(
Aggregation.lookup(mongoTemplate.getCollectionName(Component.class),
"componentUuId", "uuId", "component")
);
AggregationResults<NodeExpanded> results = mongoTemplate.aggregate(agg, mongoTemplate.getCollectionName(Node.class), NodeExpanded.class);
return results.getMappedResults();
}
使用一个简单的NodeExpanded类作为
public class NodeExpanded implements Serializable {
private String uuId;
private Component component;
}
我在mongoTemplate上得到了相同的空指针异常。聚合()指令
解决了的
问题来自SensorPersistenceService,它没有@Autowired MongoTemplate。根据那篇文章中给出的信息,不可能找出错误原因。再次感谢@Valijon在这次任务中的帮助^^
可能问题是NodeExpanded期望单个Component和Products,但是$lookup
聚合返回两个的数组
。
如果您添加额外的$project
阶段,它应该可以解决您的问题。
Aggregation agg = Aggregation.newAggregation(
Aggregation.lookup(mongoTemplate.getCollectionName(Component.class),
"componentUuId", "uuId", "component"),
Aggregation.lookup(mongoTemplate.getCollectionName(Product.class),
"component.productUuId", "uuId", "product"),
Aggregation.project()
.andInclude("uuId") //put here all fields for NodeExpanded
.and(ArrayOperators.ArrayElemAt.arrayOf("component").elementAt(0)).as("component")
.and(ArrayOperators.ArrayElemAt.arrayOf("product").elementAt(0)).as("product")
);
有人能帮我把这个mongoDB聚合转换成Spring数据mongo吗? 我试图在每个邀请函文件中获得未提醒与会者的电子邮件列表。 让它在mongo shell中运行,但需要在Spring data mongo中运行。 我的shell查询 ) 正如你们所看到的,这是我提出的,它在管道的项目和团队运作中并没有像预期的那样发挥作用。下面给出了生成的查询。 聚合对象创建 它创建以下查询 聚合对象生成的查询
我在mongodb 4.0中使用Spring(boot)数据2.2.7。我已经设置了3个集合,试图通过聚合查找操作加入这些集合。 目录 股票 操作 目录 映射由 股票 映射由 productId字段引用目录集合中的_id字段 操作 映射由 组件ID字段指的是库存集合中的_id 我想查询操作或库存收集,以检索相应的节点或组件对象列表,该列表由Product.model字段(在目录集合中)排序。) 虽
有人知道如何使用Spring-Data将下面的聚合函数转换成java代码吗?
我的应用程序使用Spring数据MongoDB,我试图在嵌入式文档中按降序排序数据,这是不工作的。 请参考以下JSON文档 JSON-库存文件: Spring数据Mongodb聚合查询: 电流输出: 苹果:150.0 李子:200.0 橙子:500.0 预期产量(按需求描述订单): 橙子:500.0 李子:200.0 苹果:150.0 你能帮我按降序得到预期的输出吗? 此外,我计划通过使用上述带限
但在我看来不对。有人能建议别的方法做这件事吗。
我有包含以下模式的文档的集合。我想过滤/查找所有包含性别女性的文档并汇总大脑评分的总和。我尝试了下面的语句,它显示了无效的管道错误。 架构: