2016-03-30 3 views
0

У меня возник вопрос о запросе mongodb.MongoDB Query ExpiredItem

{ 
"_id" : ObjectId("56e56d8a5fedaa00532886a4"), 
"UserID" : "89", 
"Trash" : [ 
    { 
     "Type" : "File", 
     "ID" : "56f948a4b9efe604ac217eb1", 
     "ParentFolder" : "0", 
     "ExpiredIn" : ISODate("2016-04-30T14:34:54.649+0000") 
    }, 
    { 
     "Type" : "Folder", 
     "ID" : "57f918a4b8efe604ac227eb5", 
     "ParentFolder" : "0", 
     "ExpiredIn" : ISODate("2016-04-27T14:34:54.649+0000") 
    } 
] 

}

мне нужны предметы, которые истекли. Как я могу это сделать? Некоторые запросы манго настолько сложны.

С наилучшими пожеланиями Хендрик

+0

Вы хотите сказать, что хотите все документы, в которых 'ExpiredIn

ответ

1

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

pipeline = [ 
    { 
     "$match": { "Trash.ExpiredIn": { "$lte": new Date() } } 
    }, 
    { 
     "$project": { 
      "ExpiredTrashItems": {         
       "$filter": { 
        "input": "$Trash", 
        "as": "el", 
        "cond": { "$lte": [ "$$el.ExpiredIn", new Date() ] } 
       }         
      } 
     } 
    } 
] 
db.collection.pipeline(pipeline) 

выше трубопровод использует оператор $filter доступный для MongoDB 3.2, чтобы произвести массив, который удовлетворяет заданному условию то есть он фильтрует внешние элементы, которые не удовлетворяют критериям.


В качестве альтернативного решения, которое не использует оператор в $filter, рассмотрим

pipeline = [ 
    { 
     "$match": { "Trash.ExpiredIn": { "$lte": new Date() } } 
    }, 
    { 
     "$project": { 
      "ExpiredTrashItems": {        
       "$setDifference": [ 
        { 
         "$map": { 
          "input": "$Trash", 
          "as": "el", 
          "in": { 
           "$cond": [ 
            { "$lte": [ "$$el.ExpiredIn", new Date() ] }, 
            "$$el", 
            false 
           ] 
          } 
         } 
        }, 
        [false] 
       ]         
      } 
     } 
    } 
] 
db.collection.pipeline(pipeline) 

$project этап трубопровода включает в себя фильтрацию Trash массив таким образом, чтобы удалить документы, которые не имеют но истек, т.е. их поле ExpiredIn больше, чем текущее время. Эта фильтрация стала возможной благодаря операторам $setDifference и $map.

Оператор $map по существу создает новое поле массива, которое содержит значения в результате оцениваемой логики в подвыражении каждому элементу массива. Оператор $setDifference возвращает набор с элементами, которые отображаются в первом наборе, но не во втором наборе; т. е. выполняет относительный комплимент второго набора относительно первого. В этом случае он вернет окончательный массив Trash, который имеет элементы с датой ExpiredIn, меньшей или равной текущему дате времени, то есть истекшему.


Для решения, которое использует оператор в $unwind, хотя не является идеальным, поскольку это создает копию каждого документа на элемент массива, таким образом, использует больше памяти и займет больше времени для обработки, чем предыдущие методы, выполнить следующую команду трубопровод:

pipeline = [ 
    { 
     "$match": { "Trash.ExpiredIn": { "$lte": new Date() } } 
    }, 
    { "$unwind": "$Trash" }, 
    { 
     "$match": { "Trash.ExpiredIn": { "$lte": new Date() } } 
    }, 
    { 
     "$group": { 
      "_id": null 
      "ExpiredTrashItems": { "$push": "$Trash" } 
     } 
    } 
] 
db.collection.pipeline(pipeline)