3.6之前的mongobd lookup 只能是形如
{
$lookup:
{
from: <collection to join>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
as: <output array field>
}
}
但是我現在的需求是除了關聯字段外,關聯的外表還有其他的字段需要篩選,百度後,參考這篇文章解決了問題
http://www.voidcn.com/article/p-pzacpwea-buq.html
我的查詢bson
db.document.aggregate([
{
$match: {
$or:
[{
"name": "xxxx"
}, {
"no": "xxxx"
}]
}
},
{
$lookup:
{
from: "document1",
let: {
name: "$name",
code: "$no"
},
pipeline: [
{
$match:
{
$expr:
{
$or:
[
{
$eq: ["$name", "$$name"]
},
{
$eq: ["$code", "$$code"]
}
]
}
}
}
],
as: "document1"
}
},
{
$lookup:
{
from: "document2",
let: {
name: "$name",
code: "$no"
},
pipeline: [
{
$match:
{
$expr:
{
$or:
[
{
$eq: ["$name", "$$name"]
},
{
$eq: ["$code", "$$code"]
}
]
}
}
}
],
as: "document2"
}
},
{
$lookup:
{
from: "document3",
let: {
name: "$name",
code: "$no"
},
pipeline: [
{
$match:
{
$expr:
{
$or:
[
{
$eq: ["$name", "$$name"]
},
{
$eq: ["$code", "$$code"]
}
]
}
}
}
],
as: "document3"
}
},
{
$lookup:
{
from: "document4",
let: {
name: "$name",
code: "$no"
},
pipeline: [
{
$match:
{
$expr:
{
$or:
[
{
$eq: ["$name", "$$name"]
},
{
$eq: ["$code", "$$code"]
}
]
}
}
}
],
as: "document4"
}
},
{
$lookup:
{
from: "document5",
let: {
name: "$name",
code: "$no"
},
pipeline: [
{
$match:
{
$expr:
{
$or:
[
{
$eq: ["$name", "$$name"]
},
{
$eq: ["$code", "$$code"]
}
]
}
}
}
],
as: "document5"
}
},
{
$lookup:
{
from: "document6",
let: {
name: "$name",
code: "$no"
},
pipeline: [
{
$match:
{
$expr:
{
$or:
[
{
$eq: ["$name", "$$name"]
},
{
$eq: ["$code", "$$code"]
}
]
}
}
}
],
as: "document6"
}
},
{
$project: {
"total1": {
"$size": "$document1"
},
"total2": {
"$size": "$document2"
},
"total3": {
"$size": "$document3"
},
"total4": {
"$size": "$document4"
},
"total5": {
"$size": "$document5"
},
"total6": {
"$size": "$document6"
}
}
}
])
java 寫法
private void numsInfoUpdate(Map<String,Object> map){
Bson filters = Aggregates.match(Filters.or(Filters.in("name",map.get("name),Filters.in("no",map.get("no))));
Bson group = Aggregates.group("$name"
,new BsonField("code",new BasicDBObject("$first","$code"))
,new BsonField("count",new BasicDBObject("$sum",1))
);
List<Bson> groupBson = new ArrayList<>();
groupBson.add(filters);
groupBson.add(group);
Bson match = Aggregates.match(Filters.or(Filters.eq("name",name),Filters.eq("no",code)));
List<Variable<String>> lets = returnLets();
List<Bson> pipelines = returnPipelines();
Bson lookup = Aggregates.lookup("document1" ,lets,pipelines,"document1");
Bson lookup1 = Aggregates.lookup("document2" ,lets,pipelines,"document2");
Bson lookup2 = Aggregates.lookup("document3" ,lets,pipelines,"document3");
Bson lookup3 = Aggregates.lookup("document4" ,lets,pipelines,"document4");
Bson lookup4 = Aggregates.lookup("document5" ,lets,pipelines,"document5");
Bson lookup5 = Aggregates.lookup("document6" ,lets,pipelines,"document6");
Bson project = Aggregates.project(Projections.fields(
Projections.include("corpName")
,new BasicDBObject("total1" ,new BasicDBObject("$size", "$document1"))
,new BasicDBObject("total2" ,new BasicDBObject("$size", "$document2"))
,new BasicDBObject("total3" ,new BasicDBObject("$size", "$document3"))
,new BasicDBObject("total4" ,new BasicDBObject("$size", "$document4"))
,new BasicDBObject("total5" ,new BasicDBObject("$size", "$document5"))
,new BasicDBObject("total6" ,new BasicDBObject("$size", "$document6"))
));
List<Bson> bsonList = new ArrayList<>();
bsonList.add(match);
bsonList.add(lookup);
bsonList.add(lookup1);
bsonList.add(lookup2);
bsonList.add(lookup3);
bsonList.add(lookup4);
bsonList.add(lookup5);
bsonList.add(project);
AggregateIterable<Document> aggregate = aggregate("document",bsonList);
}
private List<Variable<String>> returnLets() {
List<Variable<String>> lets = new ArrayList<>();
Variable<String> let1 = new Variable<>("name", "$name");
Variable<String> let2 = new Variable<>("code", "$no");
lets.add(let1);
lets.add(let2);
return lets ;
}
private List<Bson> returnPipelines() {
Bson pipeline = new BasicDBObject("$match",
new BasicDBObject("$expr",
new BasicDBObject("$or", new BasicDBObject[]{
new BasicDBObject("$eq", new String[]{"$name", "$$name"}),
new BasicDBObject("$eq", new String[]{"$code", "$$code"})
})
));
List<Bson> pipelines = new ArrayList<>();
pipelines.add(pipeline);
return pipelines ;
}
一開始參照上面鏈接中的文章時,我的代碼總報錯,其實心裏隱約明白,大概是monggodb的maven版本低了。於是項目全局搜索,發現是這樣引用的maven
是spring管理的mongo包,再ctrl鼠標點進去看到
是3.6哇,怎麼代碼始終報錯呢,於是去maven 官網倉庫找最新的引用,發現都到3.12了。但是項目現在很多地方已經引用了spring管理的mongobd的包,如果直接換成新版本的包,會有大量代碼改動,百度後,這樣解決
<!-- mongo start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<exclusions>
<exclusion>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.12.3</version>
</dependency>
<!-- mongo end -->
即,需要什麼包,就告訴maven移除原來的包