Создание запроса $ lookup между двумя коллекциями в поле ObjectId - PullRequest
0 голосов
/ 16 мая 2018

Я работаю над API в Go 1.9.2 с mongoDB 3.4 Я использую mgo в качестве драйвера.

Я должен сделать конечную точку для получения результатов запросов после вставки запроса и его результатов в одну базу данных с двумя коллекциями.

Имеет две коллекции:

Первая коллекция: requests

Вторая коллекция: results

Коллекция requests имеет формат

{ "_id":ObjectId("5afc034f53c9a77a598c8345")
  "  time ":"2018-05-16 10:08:35.024352907 +0000 UTC m=+23.407317980"
  "param_request":[name:"mike",age:"30",job:"Doctor"]
}

Коллекция results имеет формат, поле id_request - это поле _id для документа запроса (как философия внешнего ключа в SQL)

{"_id":ObjectId("5afc035b53c9a77a598c8346")
 "id_request":ObjectId("5afc034f53c9a77a598c8345")
 "name":"Mike"
 "age":"30"
 "job":"Doctor"
 "city":"Tokyo"} 

{"_id":ObjectId("5afc035b53c9a77a598c8347")
 "id_request":ObjectId("5afc034f53c9a77a598c8345")
 "name":"Mike"
 "age":"30"
 "job":"Doctor"
 "city":"London"}


 {"_id":ObjectId("5afc035b53c9a77a598c8349")
 "id_request":ObjectId("5afc034f53c9a77a598c8345")
 "name":"Mike"
 "age":"30"
 "job":"Doctor"
 "city":"Berlin"
 } 

Я попытался сделать запрос и нашел справку из документации $ lookup Documentation

желаемый результат:

 {
 "name":"Mike"
 "age":"30"
 "job":"Doctor"
 "city":"Berlin"

 }

 {
 "name":"Mike"
 "age":"30"
 "job":"Doctor"
 "city":"London"

 }

 {
 "name":"Mike"
 "age":"30"
 "job":"Doctor"
 "city":"Tokyo"

}

Вот что я сделал:

 db.results.aggregate([

  {$lookup: {from:requests, localField: "id_request",foreignField:"_id",as:”results”}},
  {$match:
         { 
      "id_request": ObjectId("5afc034f53c9a77a598c8345") }}]);

вот ошибка получения:

2018-05-16T11:31:51.261+0000 E QUERY [thread1] SyntaxError: missing } after property list @(shell):1:131

Вот что я должен получить с помощью философии SQL как запроса:

  select results .* from results join requests on 

  (results.request_id=requests._id 

               and 

    request_id='ObjectId("5afc034f53c9a77a598c8345")');

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Если вы добавите два дополнительных шага в свой конвейер, $ unwind и $ project, вы получите желаемые результаты. Я также выполнил бы $ match перед поиском в $, вы также можете искать только те данные, которые вам нужны.

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

match := bson.M{"$match": bson.M{"id_request": bson.ObjectIdHex("5afc034f53c9a77a598c8345")}}
lookup := bson.M{"$lookup": bson.M{"from": "requests", "localField": "id_request", "foreignField": "_id", "as": "results"}}
unwind := bson.M{"$unwind": "$results"}
project := bson.M{"$project": bson.M{"_id": 0, "name": 1, "job": 1, "age": 1, "city": 1}}

iter := theCollection.Pipe([]bson.M{match, lookup, unwind, project}).Iter()
answer := bson.M{}
for iter.Next(&answer) {
    fmt.Println(answer)
}
iter.Close()
0 голосов
/ 16 мая 2018

Запрос в вашем вопросе имеет несколько проблем, которые могут вызвать ошибки синтаксического анализа. Свойство from на этапе поиска должно быть строкой. Кроме того, символ кавычки, который вы использовали для свойства as (), не является допустимым разделителем строк.

Попробуйте заменить from: requests на from: "requests" и символ одинарной или двойной кавычкой.

db.results.aggregate([
   { $lookup: { from: "requests", localField: "id_request", foreignField: "_id", as: "results" } },
   { $match: { "id_request": ObjectId("5afc034f53c9a77a598c8345") } } 
]);
...