2015-08-26 1 views
-1

Если у меня есть несколько документов в коллекции MongoDB, которые выглядят следующим образом:MongoDB как нажать несколько объектов в коллекции в массив

// document 1 
{ 
    _id: '123', 
    date: '5/10/15', 

    charges: [{ 
     amount: 500, 
     description: 'foo', 
    },{ 
     amount: 400, 
     description: 'bar', 
    }], 
} 


// document 2  
{ 
    _id: '456', 
    date: '5/11/15', 

    charges: [{ 
     amount: 500, 
     description: 'foo', 
    },{ 
     amount: 300, 
     description: 'foo', 
    }], 
} 

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

[{ 
    amount: 500, 
    description: 'foo' 
}, { 
    amount: 500, 
    description: 'foo' 
}] 

Что является наиболее эффективным способом достижения этого?

ответ

2

Попробуйте это:

db.collection.aggregate(
    [ 
     { 
      $unwind: "$charges" 
     }, 
     { 
      $match: { 
       amount: 500 
      } 
     } 
    ] 
); 
0

Across документов использовать aggregation framework с $unwind и $group:

db.collection.aggregate([ 
    // Match documents with the required criteria 
    { "$match": { "charges.amount": 500 } }, 

    // Unwind to de-normalize the content 
    { "$unwind": "$charges" }, 

    // Filter the de-normalized documents 
    { "$match": { "charges.amount": 500 } }, 

    // Group back the result 
    { "$group": { 
     "_id": null, 
     "charges": { "$push": "$charges" } 
    }}   
]) 

Или немного более эффективным в современных версиях является фильтровать массив первых:

db.collection.aggregate([ 
    // Match documents with the required criteria 
    { "$match": { "charges.amount": 500 } }, 

    // Pre filter the array 
    { "$redact": { 
     "$cond": { 
      "if": { "$eq": [{ "$ifNull": [ "$amount", 500 ] }, 500 ]}, 
      "then": "$$DESCEND", 
      "else": "$$PRUNE" 
     } 
    }}, 

    // Unwind to de-normalize the content 
    { "$unwind": "$charges" }, 

    // Group back the result 
    { "$group": { 
     "_id": null, 
     "charges": { "$push": "$charges" } 
    }}   
]) 

Будущие версии (работающие в текущих версиях развития) будет иметь более полезный $filter метод:

db.collection.aggregate([ 
    // Match documents with the required criteria 
    { "$match": { "charges.amount": 500 } }, 

    // Filter the array 
    { "$project": { 
     "charges": { 
      "$filter": { 
       "input": "$charges", 
       "as": "charge", 
       "cond": { 
        "$eq": [ "$$charge.amount", 500 ] 
       } 
      } 
     } 
    }}, 

    // Unwind to de-normalize the content 
    { "$unwind": "$charges" }, 

    // Group back the result 
    { "$group": { 
     "_id": null, 
     "charges": { "$push": "$charges" } 
    }}   
]) 

Все результат:

{ 
    "_id": null, 
    "charges": [ 
     { 
      amount: 500, 
      description: 'foo' 
     }, { 
      amount: 500, 
      description: 'foo' 
     } 
    ] 
} 
Смежные вопросы