2015-01-25 3 views
0

У меня есть сценарий, где I думаю Возможно, мне понадобится использовать $ cond для установки атрибута в $ project (aggregation) в зависимости от того, существует ли существующий атрибут в массиве строки.MongoDB Фильтр для совпадающих и несогласованных условий

Возьмите следующие данные в упрощенном примере ...

var teamMemberFilter = ['Dave', 'Kate']; 

[ 
    { 
     ticketId: '1', 
     ticketDesc: 'Dummy ticket 1', 
     assignments: [ 
      { 
       asignee: 'Team', 
       email: '[email protected]' 
      }, 
      { 
       asignee: 'Dave', 
       email: '[email protected]' 
      }, 
      { 
       asignee: 'Kate', 
       email: '[email protected]' 
      } 
     ] 
    }, 
    { 
     ticketId: '2', 
     ticketDesc: 'Dummy ticket 2', 
     assignments: [ 
      { 
       asignee: 'Team', 
       email: '[email protected]' 
      }, 
      { 
       asignee: 'Rob', 
       email: '[email protected]' 
      } 
     ] 
    }, 
    { 
     ticketId: '3', 
     ticketDesc: 'Dummy ticket 3', 
     assignments: [ 
      { 
       asignee: 'Team', 
       email: '[email protected]' 
      }, 
      { 
       asignee: 'Dave', 
       email: '[email protected]' 
      }, 
      { 
       asignee: 'Mark', 
       email: '[email protected]' 
      } 
     ] 
    } 
] 

Я хотел бы запрос, который возвращает все билеты с назначением команды и не имеет назначения для члена команды.

В приведенном выше примере должен быть возвращен только билет 2, так как он имеет задание команды, а единственное другое задание в одном и том же билете принадлежит Rob, который не является частью этой команды (как указано в teamMemberFilter).

+0

Вам действительно нужно ** проецировать это? Или вы просто пытаетесь получить документы, соответствующие этим условиям? –

+0

Просто документы, соответствующие условиям, я, вероятно, слишком усложняю! – PixelSheep

ответ

1

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

db.tickets.find({ 
    "$and": [ 
     { "assignments.asignee": "Team" }, 
     { "assignments.asignee": {"$nin": teamMemberFilter } } 
    ] 
}) 

Матчи все, что имеет «Team» в качестве «asignee», но не имеет любой из перечисленных элементов.

Если по какой-то причине вы действительно нужна логика быть оценены в трубопроводе агрегации, то вы можете применить то же самое с логическими операторами, вместо:

db.tickets.aggregate([ 
    { "$project": { 
    "matched": { 
     "$let": { 
     "vars": { 
      "names": { "$map": { 
      "input": "$assignments", 
      "as": "a", 
      "in": "$$a.asignee" 
      }} 
     }, 
     "in": { 
      "$and": [ 
      { "$eq": [ 
       { "$size": { "$setIntersection": [ "$$names", ["Team"] ] } }, 
       1 
      ]}, 
      { "$eq": [ 
       { "$size": { "$setIntersection": [ "$$names", teamMemberFilter ] } }, 
       0 
      ]}, 
      ] 
     } 
     } 
    } 
    }} 
]) 

Это будет возвращать только true на втором документе и значительно упрощается операторами $map и $setIntersection для обработки содержимого массива.

+0

Я считаю, что это вернет билет 3, а также содержит задание Mark, которого нет в командеMemberFilter. – PixelSheep

+0

@PixelSheep Вы пробовали? Я сделал. Возвращает только один документ. –

+0

Ты гуру! Я получил оставшуюся часть запроса для работы с предложенным проектом $. Я не знаю, почему он не работает с чем-то вроде этого: $ спичкой: { $ и: [ { задания: { $ elemMatch: { 'asignee': 'Команда' }} } , { задания: { $ elemMatch: { 'asignee': { "$ нин": teamMemberFilter}} }} ] } – PixelSheep

Смежные вопросы