我在下面的列表中有重复的元素
我要根据版本和日期属性从列表中删除所有重复项
这意味着,如果有重复的元素,我得到的是具有状态actif的元素,如果没有人有状态的actif,那么我可以获得具有最近日期的那个
[
{
"_id" : ObjectId("5e1832df02f04352705457dd"),
"product":"1",
"version":{
"state":"Actif",
"name":"1.0.0"
},
"createdDate":"01/01/2020"
},
{
"_id" : ObjectId("5e1832df02f04352705457ff"),
"product":"1",
"version":{
"state":"A faire",
"name":"3.0.0"
},
"createdDate":"01/01/2020"
},
{
"_id" : ObjectId("5e1832df02f04352705457ee"),
"product":"1",
"version":{
"state":"Archiver",
"name":"2.0.0"
},
"createdDate":"02/01/2020"
},
{
"_id" : ObjectId("5e1832df02f04352705457gg"),
"product":"2",
"version":null,
"createdDate":"01/01/2020"
},
{
"_id" : ObjectId("5e1832df02f04352705457yy"),
"product":"2",
"version":{
"state":"Archiver",
"name":"2.0.0"
},
"createdDate":"02/01/2020"
},
{
"_id" : ObjectId("5e1832df02f04352705455ss"),
"product":"3",
"version":{
"state":"Archiver",
"name":"2.0.0"
},
"createdDate":"01/01/2020"
}
]
输出应如下所示:
[
{
"_id" : ObjectId("5e1832df02f04352705457dd"),
"product":"1",
"version":{
"state":"Actif",
"name":"1.0.0"
},
"createdDate":"01/01/2020"
},
{
"_id" : ObjectId("5e1832df02f04352705457yy"),
"product":"2",
"version":{
"state":"Archiver",
"name":"2.0.0"
},
"createdDate":"02/01/2020"
},
{
"_id" : ObjectId("5e1832df02f04352705455ss"),
"product":"3",
"version":{
"state":"Archiver",
"name":"2.0.0"
},
"createdDate":"01/01/2020"
}
]
public List<Product> search() {
final Query query = new Query().with(new Sort(new Order(Direction.DESC, "createdDate")));
return mongoOperations.find(query, Product.class);
}
我们如何做到这一点?
答案 0 :(得分:0)
您需要使用aggregate
方法。
未经测试!
如果AggregationOperation
希望实现toDocument
方法,请将所有BasicDBObject
更改为Document
。
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
Aggregation aggregation = newAggregation(
sort(Sort.Direction.ASC, "product", "version", "createdDate"),
group("product").last("$$ROOT").as("root"),
sort(Sort.Direction.ASC, "_id"),
//$replaceRoot
);
return mongoTemplate.aggregate(aggregation, Product.class, Product.class).getMappedResults();
db.Product.aggregate([
{
$sort: {
product: 1,
version: -1,
createdDate: -1
}
},
{
$group: {
_id: "$product",
root: {
$push: "$$ROOT"
}
}
},
{
$sort: {
_id: 1
}
},
{
$replaceRoot: {
newRoot: {
$arrayElemAt: [
{
$concatArrays: [
{
$filter: {
input: "$root",
cond: {
$eq: [
"$$this.version.state",
"Actif"
]
}
}
},
[
{
$arrayElemAt: [
"$root",
0
]
}
]
]
},
0
]
}
}
}
])
答案 1 :(得分:0)
使用Spring Data 2.2和MongoDB 3.4兼容的聚合运算符进行聚合。
MongoOperations mongoOps = new MongoTemplate(MongoClients.create(), "spr_test");
Aggregation agg = newAggregation(
project("product", "version")
.and(Concat.valueOf(SubstrCP.valueOf("createdDate").substringCP(6, 4))
.concat("-")
.concatValueOf(SubstrCP.valueOf("createdDate").substringCP(3, 2))
.concat("-")
.concatValueOf(SubstrCP.valueOf("createdDate").substringCP(0, 2)) )
.as("createdDate"),
group("product")
.push("$$ROOT").as("details")
.push("createdDate").as("createdDates"),
facet(
project("details")
.and(Size.lengthOfArray("details")).as("arrSize"),
match(where("arrSize").is(new Integer(1))))
.as("c1")
.and(
match(where("details.version.state").is("Actif" )),
project()
.and(filter("details")
.as("d")
.by(Eq.valueOf("d.version.state").equalToValue("Actif" )))
.as("details"))
.as("c2")
.and(
project("details", "createdDates")
.and(Size.lengthOfArray("details")).as("arrSize"),
match(where("arrSize").gt(new Integer(1))
.and("details.version.state").ne("Actif")),
project()
.and(filter("details")
.as("d")
.by(Eq.valueOf("d.createdDate").equalTo(Max.maxOf("createdDates"))))
.as("details"))
.as("c3"),
project()
.and(arrayOf("c1").concat("c2").concat("c3"))
.as("result"),
unwind("result"),
project()
.and(arrayOf("result.details").elementAt(0)).as("result")
);
AggregationResults<Document> results = mongoOps.aggregate(agg, "test", Document.class);
results.forEach(System.out::println);