Mongodb 在 Spring 数据中查找 $mongo
Mongodb $lookup in Spring data mongo
我是新手 Mongodb,我对 java spring.
的 $lookup 有疑问
我想在 Spring 数据
中使用这个 shell
db.NewFeed.aggregate([
{
$match : {username : "user001"}
},
{
$lookup:
{
from: "NewfeedContent",
localField: "content.contentId",
foreignField: "_id",
as: "NewfeedContent"
}
}
])
我在 Google 上找到了,但还没有答案。
并非每个 "new" 特征都会立即进入抽象层,例如 spring-mongo。
因此,您需要做的就是定义一个使用 AggregationOperation
接口的 class,它将取一个直接指定为内容的 BSON 对象:
public class CustomAggregationOperation implements AggregationOperation {
private DBObject operation;
public CustomAggregationOperation (DBObject operation) {
this.operation = operation;
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return context.getMappedObject(operation);
}
}
然后你可以像这样在聚合中使用:
Aggregation aggregation = newAggregation(
match(
Criteria.where("username").is("user001")
),
new CustomAggregationOperation(
new BasicDBObject(
"$lookup",
new BasicDBObject("from", "NewFeedContent")
.append("localField","content.contentId")
.append("foreignField", "_id")
.append("as", "NewFeedContent")
)
)
)
显示自定义 class 与内置 match()
管道助手的混合。
每个助手下面发生的所有事情是它们序列化为 BSON 表示,例如 DBObject
。所以这里的构造函数只是直接获取对象,并且returns直接从.toDBObject()
,这是在序列化管道内容时将调用的接口上的标准方法。
这是一个例子:
Collection 帖子
{
"_id" : ObjectId("5a198074ed31adaf5d79fe8a"),
"title" : "Post 1",
"authors" : [1, 2]
},
{
"_id" : ObjectId("5a198074ed31adaf5d79fe8d"),
"title" : "Post 2",
"authors" : [2]
}
Collection 用户
{
"_id" : ObjectId("5a18b483ed31ada08fd6ed82"),
"userId" : 1,
"name" : "Vinod Kumar"
},
{
"_id" : ObjectId("5a18b483ed31ada08fd6ed83"),
"userId" : 2,
"name" : "Jim Hazel"
},
{
"_id" : ObjectId("5a18b483ed31ada08fd6ed84"),
"userId" : 3,
"name" : "Alex Wong"
}
Mongodb 带查找和匹配的查询
db.users.aggregate([
{
$lookup:
{
from: "users",
localField: "userid",
foreignField: "authors",
as: "post"
}
},
{
$match: { "post": { $ne: [] } }
}
]).pretty()
Spring Mongoopration 语法
LookupOperation lookupOperation = LookupOperation.newLookup().
from("posts").
localField("userid").
foreignField("authors").
as("post");
AggregationOperation match = Aggregation.match(Criteria.where("post").size(1));
Aggregation aggregation = Aggregation.newAggregation(lookupOperation, match);
List<BasicDBObject> results = mongoOperation.aggregate(aggregation, "users", BasicDBObject.class).getMappedResults();
使用 Spring 数据连接两个集合 MongoDB
员工Class
class Employee {
private String _id;
private String name;
private String dept_id;
}
部门Class
class Department {
private String _id;
private String dept_name;
}
员工结果Class
public class EmpDeptResult {
private String _id;
private String name;
private List<Object> departments;
}
员工服务Class
public class EmployeeService {
@Autowired
private MongoTemplate mongoTemplate;
private Logger LOGGER = LoggerFactory.getLogger(EmployeeService.class);
public void lookupOperation(){
LookupOperation lookupOperation = LookupOperation.newLookup()
.from("Department")
.localField("dept_id")
.foreignField("_id")
.as("departments");
Aggregation aggregation = Aggregation.newAggregation(Aggregation.match(Criteria.where("_id").is("1")) , lookupOperation);
List<EmpDeptResult> results = mongoTemplate.aggregate(aggregation, "Employee", EmpDeptResult.class).getMappedResults();
LOGGER.info("Obj Size " +results.size());
}
}
可以用下面的方式加入3个Collections
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
DB db = mongoClient.getDB( "DBname" );
BasicDBObject query = BasicDBObject.parse("{$match:{_id:61188}},\n" +
" {\n" +
" $lookup:\n" +
" {\n" +
" from: \"CustomerDetails\",\n" +
" localField: \"supplierId\",\n" +
" foreignField: \"supplierId\",\n" +
" as: \"newfield\"\n" +
" }\n" +
" }\n" +
" , {\n" +
" $lookup:\n" +
" {\n" +
" from: \"ItemDetails\",\n" +
" localField: \"supplierId\",\n" +
" foreignField: \"supplierId\",\n" +
" as: \"newfield\"\n" +
" }\n" +
" }");
AggregationOutput dumps = db.getCollection("HeaderInfo").aggregate(query);
System.out.println("result="+dumps.results());
现在回答这个问题为时已晚,但它可能会帮助其他面临同样问题的人。
如果你使用的是 spring-boot-data-mongodb-2.0 或以上版本那么有一个简单的方法来实现这个。
AggregationOperation match = Aggregation.match(Criteria.where("username").is("user001")));
AggregationOperation query = Aggregation.lookup("NewfeedContent", "content.contentId", "_id", "NewfeedContent");
// If you want to unwind
//AggregationOperation unwind = Aggregation.unwind("Patient");
Aggregation agr = Aggregation.newAggregation(query, match, unwind);
AggregationResults<Document> result = springTemplate.aggregate(agr, "CollectionName", Document.class);
我是新手 Mongodb,我对 java spring.
的 $lookup 有疑问我想在 Spring 数据
中使用这个 shelldb.NewFeed.aggregate([
{
$match : {username : "user001"}
},
{
$lookup:
{
from: "NewfeedContent",
localField: "content.contentId",
foreignField: "_id",
as: "NewfeedContent"
}
}
])
我在 Google 上找到了,但还没有答案。
并非每个 "new" 特征都会立即进入抽象层,例如 spring-mongo。
因此,您需要做的就是定义一个使用 AggregationOperation
接口的 class,它将取一个直接指定为内容的 BSON 对象:
public class CustomAggregationOperation implements AggregationOperation {
private DBObject operation;
public CustomAggregationOperation (DBObject operation) {
this.operation = operation;
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return context.getMappedObject(operation);
}
}
然后你可以像这样在聚合中使用:
Aggregation aggregation = newAggregation(
match(
Criteria.where("username").is("user001")
),
new CustomAggregationOperation(
new BasicDBObject(
"$lookup",
new BasicDBObject("from", "NewFeedContent")
.append("localField","content.contentId")
.append("foreignField", "_id")
.append("as", "NewFeedContent")
)
)
)
显示自定义 class 与内置 match()
管道助手的混合。
每个助手下面发生的所有事情是它们序列化为 BSON 表示,例如 DBObject
。所以这里的构造函数只是直接获取对象,并且returns直接从.toDBObject()
,这是在序列化管道内容时将调用的接口上的标准方法。
这是一个例子:
Collection 帖子
{
"_id" : ObjectId("5a198074ed31adaf5d79fe8a"),
"title" : "Post 1",
"authors" : [1, 2]
},
{
"_id" : ObjectId("5a198074ed31adaf5d79fe8d"),
"title" : "Post 2",
"authors" : [2]
}
Collection 用户
{
"_id" : ObjectId("5a18b483ed31ada08fd6ed82"),
"userId" : 1,
"name" : "Vinod Kumar"
},
{
"_id" : ObjectId("5a18b483ed31ada08fd6ed83"),
"userId" : 2,
"name" : "Jim Hazel"
},
{
"_id" : ObjectId("5a18b483ed31ada08fd6ed84"),
"userId" : 3,
"name" : "Alex Wong"
}
Mongodb 带查找和匹配的查询
db.users.aggregate([
{
$lookup:
{
from: "users",
localField: "userid",
foreignField: "authors",
as: "post"
}
},
{
$match: { "post": { $ne: [] } }
}
]).pretty()
Spring Mongoopration 语法
LookupOperation lookupOperation = LookupOperation.newLookup().
from("posts").
localField("userid").
foreignField("authors").
as("post");
AggregationOperation match = Aggregation.match(Criteria.where("post").size(1));
Aggregation aggregation = Aggregation.newAggregation(lookupOperation, match);
List<BasicDBObject> results = mongoOperation.aggregate(aggregation, "users", BasicDBObject.class).getMappedResults();
使用 Spring 数据连接两个集合 MongoDB
员工Class
class Employee {
private String _id;
private String name;
private String dept_id;
}
部门Class
class Department {
private String _id;
private String dept_name;
}
员工结果Class
public class EmpDeptResult {
private String _id;
private String name;
private List<Object> departments;
}
员工服务Class
public class EmployeeService {
@Autowired
private MongoTemplate mongoTemplate;
private Logger LOGGER = LoggerFactory.getLogger(EmployeeService.class);
public void lookupOperation(){
LookupOperation lookupOperation = LookupOperation.newLookup()
.from("Department")
.localField("dept_id")
.foreignField("_id")
.as("departments");
Aggregation aggregation = Aggregation.newAggregation(Aggregation.match(Criteria.where("_id").is("1")) , lookupOperation);
List<EmpDeptResult> results = mongoTemplate.aggregate(aggregation, "Employee", EmpDeptResult.class).getMappedResults();
LOGGER.info("Obj Size " +results.size());
}
}
可以用下面的方式加入3个Collections
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
DB db = mongoClient.getDB( "DBname" );
BasicDBObject query = BasicDBObject.parse("{$match:{_id:61188}},\n" +
" {\n" +
" $lookup:\n" +
" {\n" +
" from: \"CustomerDetails\",\n" +
" localField: \"supplierId\",\n" +
" foreignField: \"supplierId\",\n" +
" as: \"newfield\"\n" +
" }\n" +
" }\n" +
" , {\n" +
" $lookup:\n" +
" {\n" +
" from: \"ItemDetails\",\n" +
" localField: \"supplierId\",\n" +
" foreignField: \"supplierId\",\n" +
" as: \"newfield\"\n" +
" }\n" +
" }");
AggregationOutput dumps = db.getCollection("HeaderInfo").aggregate(query);
System.out.println("result="+dumps.results());
现在回答这个问题为时已晚,但它可能会帮助其他面临同样问题的人。 如果你使用的是 spring-boot-data-mongodb-2.0 或以上版本那么有一个简单的方法来实现这个。
AggregationOperation match = Aggregation.match(Criteria.where("username").is("user001")));
AggregationOperation query = Aggregation.lookup("NewfeedContent", "content.contentId", "_id", "NewfeedContent");
// If you want to unwind
//AggregationOperation unwind = Aggregation.unwind("Patient");
Aggregation agr = Aggregation.newAggregation(query, match, unwind);
AggregationResults<Document> result = springTemplate.aggregate(agr, "CollectionName", Document.class);