MongoDb: 如何在多个集合中进行搜索?
MongoDb: how to search in multiple collections?
我在 mongodb 中得到了这个结构(2 个集合:restaurant
和 cocktail
)
restaurant {id=1001, name="Res1", coor=[12.392, 19.123], cocktail=[13, 0, 92]}
cocktail {id=13, name="Capiroska"}, {id=167, name="Capirinha"}, {id=92, name="Negroni"}, {id=0, name="Martini"}
多个 restaurant
和多个 cocktail
,N:N 关系。
我的目标是找到我可以在特定区域内饮用哪些不同的 cocktail
s。
我已经编写了一个查询来查找我所在位置附近的所有餐馆,如下所示:
mongoTemplate.find(new Query(Criteria.where("address.location").withinSphere(new Circle(latitude, longitude, radius/6371))
), Restaurant.class);
以便我获得 restaurant
的列表。
接下来的步骤是:
如何获得不同的cocktail
的id
(不允许重复)
如何查看 cocktail
集合以获得所有 cocktail
名称
提前TY!
使用聚合怎么样。
首先执行匹配阶段,你得到所有的餐厅,然后对鸡尾酒进行放松操作,之后你可以在鸡尾酒场上进行分组。在此阶段,您拥有所有唯一的鸡尾酒 ID,然后执行查找阶段。
舞台顺序
- 匹配
- 项目如果你想要它的可选
- 放松
- 组
- 查找
- project //因为你只想要鸡尾酒的名字而不是完整的
collection.
代码在 kotlin 中,只需将其转换为 java 如果您将 intellij 用作 ide,那么它会为您将其转换为 java。
var match = Aggregation.match(Criteria.where("address.location").withinSphere(Circle(latitude, longitude, radius / 6371)))
var project = Aggregation.project("cocktail")
var unwind = Aggregation.unwind("cocktail")
var group = Aggregation.group("cocktail")
var lookup = Aggregation.lookup("your cocktail collection name","_id.cocktail","id","cocktailCollection")
var project1 = Aggregation.project("cocktailCollection.name").andExclude("_id")
var aggregation = Aggregation.newAggregation(match,project,unwind,group,lookup,project1)
println(aggregation) // if you want to see the query
var result = mongoTemplate.aggregate(aggregation,String::class.java)
这可能无法完全回答您的问题,但可以提供帮助
如何获取不同的鸡尾酒ID(不允许重复)
您的 cocktail
在数组中,因此直接 group
或 distinct
可能不起作用,您可以使用 $unwind
.
What $unwind does is allow you to peel off a document for each element
and returns that resulting document
例如:对于这个对象
{id=1001, name="Res1", coor=[12.392, 19.123], cocktail=[13, 0, 92]}
和这个查询
db.temp.aggregate( [ { $unwind: "$cocktail" } ] )
将导致
{ "_id" : 1001, "name" : "Res1", coor=[12.392, 19.123],, "cocktail" : 13 }
{ "_id" : 1001, "name" : "Res1", coor=[12.392, 19.123],, "cocktail" : 0 }
{ "_id" : 1001, "name" : "Res1", coor=[12.392, 19.123],, "cocktail" : 92 }
现在,一旦您拥有所有个人记录,您就可以按鸡尾酒分组
db.temp.aggregate( [ { $unwind: "$cocktail" },
{
"$group": {
_id: {
"_id": "$_id",
items: {$addToSet: '$cocktail'}}
}
}
}
] );
这应该可以回答您的第一个问题
要获取鸡尾酒名称,您需要像这样使用查找、分组和投影
db.temp.aggregate([
{
"$unwind": "$cocktail"
},
{
"$lookup": {
"from": "cocktail ",
"localField": "restaurant.cocktail._id",
"foreignField": "_id",
"as": "cocktails"
}
},
{ "$unwind": "$cocktails" },
{
"$group": {
"_id": "$_id",
"cocktail": { "$cocktail": "$cocktail" },
}
},
{
"$project": {
"name": 1,
"coor" : 1,
"cocktail.name" : 1,
}
}
]).pretty()
注意:这只是一种方法,可能不是最好的方法,也未经测试。
您可以使用 join in MongoDB 从两个或多个集合中搜索数据。
根据您的情况,以下链接可能会有所帮助。
我在 mongodb 中得到了这个结构(2 个集合:restaurant
和 cocktail
)
restaurant {id=1001, name="Res1", coor=[12.392, 19.123], cocktail=[13, 0, 92]}
cocktail {id=13, name="Capiroska"}, {id=167, name="Capirinha"}, {id=92, name="Negroni"}, {id=0, name="Martini"}
多个 restaurant
和多个 cocktail
,N:N 关系。
我的目标是找到我可以在特定区域内饮用哪些不同的 cocktail
s。
我已经编写了一个查询来查找我所在位置附近的所有餐馆,如下所示:
mongoTemplate.find(new Query(Criteria.where("address.location").withinSphere(new Circle(latitude, longitude, radius/6371))
), Restaurant.class);
以便我获得 restaurant
的列表。
接下来的步骤是:
如何获得不同的
cocktail
的id
(不允许重复)如何查看
cocktail
集合以获得所有cocktail
名称
提前TY!
使用聚合怎么样。
首先执行匹配阶段,你得到所有的餐厅,然后对鸡尾酒进行放松操作,之后你可以在鸡尾酒场上进行分组。在此阶段,您拥有所有唯一的鸡尾酒 ID,然后执行查找阶段。
舞台顺序
- 匹配
- 项目如果你想要它的可选
- 放松
- 组
- 查找
- project //因为你只想要鸡尾酒的名字而不是完整的 collection.
代码在 kotlin 中,只需将其转换为 java 如果您将 intellij 用作 ide,那么它会为您将其转换为 java。
var match = Aggregation.match(Criteria.where("address.location").withinSphere(Circle(latitude, longitude, radius / 6371)))
var project = Aggregation.project("cocktail")
var unwind = Aggregation.unwind("cocktail")
var group = Aggregation.group("cocktail")
var lookup = Aggregation.lookup("your cocktail collection name","_id.cocktail","id","cocktailCollection")
var project1 = Aggregation.project("cocktailCollection.name").andExclude("_id")
var aggregation = Aggregation.newAggregation(match,project,unwind,group,lookup,project1)
println(aggregation) // if you want to see the query
var result = mongoTemplate.aggregate(aggregation,String::class.java)
这可能无法完全回答您的问题,但可以提供帮助
如何获取不同的鸡尾酒ID(不允许重复)
您的 cocktail
在数组中,因此直接 group
或 distinct
可能不起作用,您可以使用 $unwind
.
What $unwind does is allow you to peel off a document for each element and returns that resulting document
例如:对于这个对象
{id=1001, name="Res1", coor=[12.392, 19.123], cocktail=[13, 0, 92]}
和这个查询
db.temp.aggregate( [ { $unwind: "$cocktail" } ] )
将导致
{ "_id" : 1001, "name" : "Res1", coor=[12.392, 19.123],, "cocktail" : 13 }
{ "_id" : 1001, "name" : "Res1", coor=[12.392, 19.123],, "cocktail" : 0 }
{ "_id" : 1001, "name" : "Res1", coor=[12.392, 19.123],, "cocktail" : 92 }
现在,一旦您拥有所有个人记录,您就可以按鸡尾酒分组
db.temp.aggregate( [ { $unwind: "$cocktail" },
{
"$group": {
_id: {
"_id": "$_id",
items: {$addToSet: '$cocktail'}}
}
}
}
] );
这应该可以回答您的第一个问题
要获取鸡尾酒名称,您需要像这样使用查找、分组和投影
db.temp.aggregate([
{
"$unwind": "$cocktail"
},
{
"$lookup": {
"from": "cocktail ",
"localField": "restaurant.cocktail._id",
"foreignField": "_id",
"as": "cocktails"
}
},
{ "$unwind": "$cocktails" },
{
"$group": {
"_id": "$_id",
"cocktail": { "$cocktail": "$cocktail" },
}
},
{
"$project": {
"name": 1,
"coor" : 1,
"cocktail.name" : 1,
}
}
]).pretty()
注意:这只是一种方法,可能不是最好的方法,也未经测试。
您可以使用 join in MongoDB 从两个或多个集合中搜索数据。 根据您的情况,以下链接可能会有所帮助。