2016-11-11 5 views
0

У меня есть массив как это:

{ 
    "_id" : ObjectId("581b7d650949a5204e0a6e9b"), 
    "types" : [ 
     { 
      "type" : ObjectId("581b7c645057c4602f48627f"), 
      "quantity" : 4, 
      "_id" : ObjectId("581b7d650949a5204e0a6e9e") 
     }, 
     { 
      "type" : ObjectId("581ca0e75b1e3058521a6d8c"), 
      "quantity" : 4, 
      "_id" : ObjectId("581b7d650949a5204e0a6e9e") 
     } 
    ], 
    "__v" : 0 
}, 
{ 
    "_id" : ObjectId("581b7d650949a5204e0a6e9c"), 
    "types" : [ 
     { 
      "type" : ObjectId("581b7c645057c4602f48627f"), 
      "quantity" : 4, 
      "_id" : ObjectId("581b7d650949a5204e0a6e9e") 
     } 
    ], 
    "__v" : 0 
} 

И я хочу, чтобы создать запрос, который будет возвращать мне, что elementswhere массив типов ALL соответствовать $ в массиве.

Например:

query([ObjectId("581b7c645057c4602f48627f"), ObjectId("581ca0e75b1e3058521a6d8c")]) 

должен возвращать элементы 1 и 2

query([ObjectId("581b7c645057c4602f48627f")]) 

должен возвращать элемент 2

query([ObjectId("581ca0e75b1e3058521a6d8c")]) 

не должен возвращать никакого отношения

Я попытался

db.getCollection('elements').find({'types.type': { $in: [ObjectId("581ca0e75b1e3058521a6d8c")]}}) 

Но он возвращает элементы, если только один типа соответствует

+0

Почему запрос ([ObjectId ("581ca0e75b1e3058521a6d8c")]) не должен ничего возвращать? –

+0

Поскольку нет элемента, который имеет только тип ObjectId («581ca0e75b1e3058521a6d8c») – Leamas

ответ

1

Вы, возможно, придется использовать агрегацию, как $ в и $ elematch будет возвращать только соответствующие элементы. Этап проекта установлен равным для создания всего флага соответствия и соответствует на последнем этапе с истинным значением.

aggregate([ { 
    $project: { 
     _id: 0, 
     isAllMatch: {$setIsSubset: ["$types.type", [ObjectId("581b7c645057c4602f48627f")]]}, 
     data: "$$ROOT" 
    } 
}, { 
    $match: { 
     isAllMatch: true 
    } 
}]) 

Пример вывода

{ 
    "isAllMatch": true, 
    "data": { 
     "_id": ObjectId("581b7d650949a5204e0a6e9c"), 
     "types": [{ 
      "type": ObjectId("581b7c645057c4602f48627f"), 
      "quantity": 4, 
      "_id": ObjectId("581b7d650949a5204e0a6e9e") 
     }], 
     "__v": 0 
    } 
} 

Альтернативная версия:

Эта версия сочетает в себе оба проекта и матч этапов в один $ красноломкий этап с оператором $ конд, чтобы решить, следует ли сохранить или подрезать элементы.

aggregate([{ 
    "$redact": { 
     "$cond": [{ 
       $setIsSubset: ["$types.type", [ObjectId("581b7c645057c4602f48627f")]] 
      }, 
      "$$KEEP", 
      "$$PRUNE" 
     ] 
    } 
}]) 
+0

Я хочу вернуть элементы, а не типы. И я думаю, что $ setEquals не будет работать, поскольку я хочу проверить, все ли элементы в массиве заданы как параметр. – Leamas

+0

Возвращает элемент с типами. вы можете передать любой массив в isAllMatch в конвейере группы. пожалуйста, обновите свой пост именно тем, что хотите увидеть вывод и ввод, который вы передаете. – Veeram

+0

Спасибо за ответ. $ setEquals: ['$ types.type', myTypes], похоже, не выполняет эту работу. Это правда, только если '$ types.type' как те же элементы, что и myTypes. Я хочу, чтобы это было правдой, если ВСЕ элементы в $ types.type находятся в myTypes. Если $ types.type = [1, 2] и myTypes = [1, 2, 3], я хочу вернуть элемент. Прямо сейчас, он не возвращает его – Leamas