MongoDb: 如何在多个集合中进行搜索?

MongoDb: how to search in multiple collections?

我在 mongodb 中得到了这个结构(2 个集合:restaurantcocktail

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 关系。

我的目标是找到我可以在特定区域内饮用哪些不同的 cocktails。

我已经编写了一个查询来查找我所在位置附近的所有餐馆,如下所示:

mongoTemplate.find(new Query(Criteria.where("address.location").withinSphere(new Circle(latitude, longitude, radius/6371))
            ), Restaurant.class);

以便我获得 restaurant 的列表。

接下来的步骤是:

  1. 如何获得不同的cocktailid(不允许重复)

  2. 如何查看 cocktail 集合以获得所有 cocktail 名称

提前TY!

使用聚合怎么样。

首先执行匹配阶段,你得到所有的餐厅,然后对鸡尾酒进行放松操作,之后你可以在鸡尾酒场上进行分组。在此阶段,您拥有所有唯一的鸡尾酒 ID,然后执行查找阶段。

舞台顺序

  1. 匹配
  2. 项目如果你想要它的可选
  3. 放松
  4. 查找
  5. 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 在数组中,因此直接 groupdistinct 可能不起作用,您可以使用 $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 从两个或多个集合中搜索数据。 根据您的情况,以下链接可能会有所帮助。

https://www.mongodb.com/blog/post/joins-and-other-aggregation-enhancements-coming-in-mongodb-3-2-part-1-of-3-introduction