我有一个类似于以下内容的Mongo DB集合:
{
"_id": "...",
"name": "name 1",
"created": "2020-07-21T08:11:18.414+00:00",
"tags": ["red", "green"]
}
{
"_id": "...",
"name": "name 2",
"created": "2020-07-20T08:11:18.414+00:00",
"tags": ["red", "blue"]
}
{
"_id": "...",
"name": "name 3",
"created": "2020-07-19T08:11:18.414+00:00",
"tags": ["green", "blue"]
}
{
"_id": "...",
"name": "name 4",
"created": "2020-07-18T08:11:18.414+00:00",
"tags": ["white", "blue"]
}
{
"_id": "...",
"name": "name 5",
"created": "2020-07-17T08:11:18.414+00:00",
"tags": ["white", "green"]
}
我需要能够指定标签列表,并且对于列表中的每个标签,我都需要获取最新创建的文档。在上面的示例中,如果指定["red", "green", "blue"]
,则应得到类似于以下结果:
{
"red": {
"_id": "...",
"name": "name 1",
"created": "2020-07-21T08:11:18.414+00:00",
"tags": ["red", "green"]
},
"green": {
"_id": "...",
"name": "name 1",
"created": "2020-07-21T08:11:18.414+00:00",
"tags": ["red", "green"]
},
"blue": {
"_id": "...",
"name": "name 2",
"created": "2020-07-20T08:11:18.414+00:00",
"tags": ["red", "blue"]
}
}
我的问题是:
AggregationOperation
?我对问题1的回答很满意,我可以分别寻找问题2的答案。
如前所述,您可以通过聚合来实现
$sort
在创建由下降到订单$facet
有助于对我们$match
用来过滤标签的内部文档进行分类$project
有助于投影。我们已经按创建了排序。因此,我们将通过获取第一个元素$arrayElemAt
,有时,如果没有元素,它将引发异常,因此,为了返回空对象,我们使用$ifNull
Mongo脚本
[
{
$sort: {
created: -1
}
},
{
$facet: {
red: [
{
$match: {
tags: "red"
}
}
],
green: [
{
$match: {
tags: "green"
}
}
],
blue: [
{
$match: {
tags: "blue"
}
}
]
}
},
{
$project: {
red: {
$ifNull: [
{
"$arrayElemAt": [
"$red",
0
]
},
{}
]
},
blue: {
$ifNull: [
{
"$arrayElemAt": [
"$blue",
0
]
},
{}
]
},
green: {
$ifNull: [
{
"$arrayElemAt": [
"$green",
0
]
},
{}
]
}
}
}
]
工作蒙戈游乐场
当我们将其转换为Spring数据时
public List<Object> test() {
Aggregation aggregation = Aggregation.newAggregation(
sort(Sort.Direction.DESC, "created"),
facet(
match(Criteria.where("tags").is("red"))
).as("red")
.and(
match(Criteria.where("tags").is("green"))
).as("green")
.and(
match(Criteria.where("tags").is("blue"))
).as("blue"),
project()
.and(ConditionalOperators.ifNull(ArrayOperators.arrayOf("red").elementAt(0)).then(new Document())).as("red")
.and(ConditionalOperators.ifNull(ArrayOperators.arrayOf("blue").elementAt(0)).then(new Document())).as("blue")
.and(ConditionalOperators.ifNull(ArrayOperators.arrayOf("green").elementAt(0)).then(new Document())).as("green")
).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());
return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(YOUR_COLLECTION.class), Object.class).getMappedResults();
}
注意:我没有在spring-boot中测试以上代码。但是它是基于有效的mongo脚本编写的。希望它能工作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句