MongoDb: как искать в нескольких коллекциях? - PullRequest
0 голосов
/ 23 мая 2019

Я получил эту структуру в моем 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 с.

Следующие шаги:

  1. Как получить отличительные cocktail id (повторы не допускаются)

  2. Как просмотреть cocktail коллекцию, чтобы получить все cocktail имена

TY заранее!

Ответы [ 3 ]

0 голосов
/ 23 мая 2019

Это может не полностью ответить на ваш вопрос, но может помочь

как получить отдельный идентификатор коктейля (повторы не допускаются)

Ваш cocktail находится в массиве, поэтому прямой group или distinct может не работать, вы можете использовать $unwind.

То, что делает $ unwind, позволяет вам отделять документ для каждого элемента и возвращает полученный документ

Например: для этого объекта

{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()

Примечание: Это всего лишь один из подходов, который может быть не лучшим и не проверенным.

0 голосов
/ 23 мая 2019

Вы можете искать данные из двух или более коллекций, используя объединение в MongoDB.В зависимости от вашего сценария могут помочь следующие ссылки.

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

0 голосов
/ 23 мая 2019

как насчет использования агрегации.

сначала выполните стадию матча, на которой вы получите весь ресторан, затем выполните операцию размотки коктейля, после чего вы можете выполнить групповое на коктейльном поле. На этом этапе у вас есть все уникальные идентификаторы коктейлей, а затем выполните этап поиска.

Порядок этапа

  1. совпадение
  2. проект, если вы хотите его необязательный
  3. размотать
  4. группа
  5. поиск
  6. проект // потому что вы хотите только название коктейля вместо полного коллекция.

Код на 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)
...