2017-02-07 7 views
4

У меня есть следующий код: Монго

db.users.aggregate([ 
    { 
     $match: { 
      $and: [ 
       { UserName: { $eq: 'administrator' } }, 
       { 'Company.CompanyName': { $eq: 'test' } } 
      ]     
     } 
    }, 
    { 
     $lookup: { 
      from: "companies", 
      localField: "CompanyID", 
      foreignField: "CompanyID", 
      as: "Company" 
     } 
    }, 
]) 

$lookup часть кода работает прекрасно. Я получил следующий результат:

enter image description here enter image description here

Но если добавить $match к коду, она не приносит ничего.

Я обнаружил, что проблема заключается во втором матче: { 'Company.CompanyName': { $eq: 'test' } }, но я не могу понять, что с ним не так. Любые идеи?

UPDATE:

Я также пытался $unwind на $lookup результат, но не повезло:

db.users.aggregate([ 
    { 
     $match: { 
      $and: [ 
       { UserName: { $eq: 'administrator' } }, 
       { 'Company.CompanyName': { $eq: 'edt5' } } 
      ] 
     } 
    }, 
    { unwind: '$Company' }, 
    { 
     $lookup: { 
      from: 'companies', 
      localField: 'CompanyID', 
      foreignField: 'CompanyID', 
      as: 'Company' 
     } 
    }, 
]) 
+0

Две точки: 1: вы можете скопировать в качестве примера записи вы думаете, что должен возвращаться? Ваш скриншот не идеален, потому что данные компании отключены до того, как будет показано поле CompanyName. 2: возникает ли у вас такая же проблема, если вы запускаете только секцию $ match, т. Е. Без поиска $ unwind или $? –

+0

@VinceBowdren 1) Добавлено новое изображение с полным объектом компании.2) $ match с именем пользователя работает только хорошо, но поле компании становится только с поиском, так как я могу проверить его без $ lookup? – AlexBerd

+3

После $ lookup вам нужно будет развернуть 'Company'. Добавить этап $ match на поле компании после $ unwind – Veeram

ответ

6

С MongoDB 3.4, вы можете запустить трубопровод агрегации, который использует трубопровод в $addFields и a $filter Оператор возвращает только массив Company с элементами, соответствующими данному условию. После этого вы можете обернуть выражение в $filter с оператором на $arrayElemAt вернуть единый документ, который по сути включает в себя функциональность $unwind уплощения массива.

Следуйте этот пример, чтобы понять выше понятие:

db.users.aggregate([ 
    { "$match": { "UserName": "administrator" } }, 
    { 
     "$lookup": { 
      "from": 'companies', 
      "localField": 'CompanyID', 
      "foreignField": 'CompanyID', 
      "as": 'Company' 
     } 
    }, 
    { 
     "$addFields": { 
      "Company": { 
       "$arrayElemAt": [ 
        { 
         "$filter": { 
          "input": "$Company", 
          "as": "comp", 
          "cond": { 
           "$eq": [ "$$comp.CompanyName", "edt5" ] 
          } 
         } 
        }, 0 
       ] 
      } 
     } 
    } 
]) 
+0

Вы избили меня до него. Возможно, вам придется переместить этап $ addFields после поиска и удалить часть 'CompanyName' из' $ match'. Я думаю, что 'CompanyName' - это поле в просмотренной коллекции. – Veeram

+0

@Veeram. Вы правы, спасибо, что заметили. Я обновил ответ, чтобы включить исходный желаемый запрос OP. Ура! – chridam