mongodb - Spring mongo slice array in embedded document
问题描述
The slice method in aggreation for array within an embedded document is not working for me using spring mongo template.
Example:
Invoice collection:
{
"reference_number": "aaa111",
"historical_data": {
"year": 2010,
"data": [
{
"item_name": "Apple",
"price": 50
},
{
"item_name": "Book",
"price": 200
}
]
}
}
Using mongoTemplate I would like to get only the historical data in slices.
For the arrays which needs to be sliced that appear directly under the root I had found a solution using aggregation Refer : Spring mongo repository slice
Applying a similar query for array in an embedded document returns an empty list even if there is data.
The query that I was trying was :
TypedAggregation<Invoice> agg = newAggregation(Invoice.class,
match(where("reference_number").is(referenceNumber)),
project.andExpression("historicalData.data").slice(limit, offset));
AggregationResults<Invoice> result = mongoTemplate.aggregate(agg, Invoice.class, Invoice.class);
But this returns an empty list of data.
Is there any other alternative way to get the sliced result for arrays within an embedded document?
Invoice.java
@Data
@Document(collection = "invoice")
public class Invoice {
@Id
private String id;
@NotEmpty
@Indexed(unique = true)
@Field("reference_number")
private String referenceNumber = UUID.randomUUID().toString();
@Valid
@Field("historical_data")
private HistoricalData historicalData = new HistoricalData();
}
HistoricalData:
@Data
public class HistoricalData {
@NotEmpty
@Field("year")
private Intger year;
@Valid
@NotNull
@Field("data")
private List<InvoiceData> data = new LinkedList<>();
}
Note : I have also tried :
TypedAggregation<Invoice> agg = newAggregation(Invoice.class,
match(where("reference_number").is(referenceNumber)),
project.andExpression("historical_data.data").slice(limit, offset));
AggregationResults<Invoice> result = mongoTemplate.aggregate(agg, Invoice.class, Invoice.class);
But this gave me a PropertyPathException.
Thanks in advance!!
解决方案
经过一周的努力,我找到了解决方案:
ProjectionOperation project = project().and("historicalRevisionData.data").slice(limit, offset).as("historical_revision_data.data")
.andInclude("id")
.and("referenceNumber").as("reference_number");
TypedAggregation<Invoice> agg = newAggregation(Invoice.class,
match(where("reference_number").is(referenceNumber)),
project);
AggregationResults<TaxInvoice> aggregate = mongoTemplate.aggregate(agg, Invoice.class, Invoice.class);
希望这对其他人也有帮助。
推荐阅读
- c++ - OpenCV从相机中每行读取的像素太少
- pine-script - Pine 中的简单时间策略
- python - 如何管理功能以高效使用美汤
- swiftui - 如何在 iPad 上的 SwiftUI 拆分视图中更改主视图宽度
- c++ - 此树实现未显示任何输出
- c# - C# 测试文件与 .NetCore 控制台应用程序中用户的 linux 主路径一起存在
- python - Python Tkinter 项目中的 IndexError
- go - 如何使用自定义错误消息进行 OpenAPI 组件验证?
- azure-ad-b2c - Azure AD B2C 需要添加自定义页面
- python - 在 Python 中将字符串输入转换为 matplotlib.pyplot 的变量