2015-11-29 4 views
1

Например, если у меня есть следующий объект в MongoDB:Есть ли способ получить длину поля объекта в mongodb?

{ 
    { 
     "name": "pencil", 
     "purchase_record": { 
      "1":"$900", 
      "2":"$1000", 
      "3":"$1100", 
      "4":"$1200" 
     } 
    }, 
    { 
     "name": "pen", 
     "purchase_record": { 
      "1":"$1000", 
      "2":"$1200", 
      "3":"$900", 
      "4":"$1100", 
      "5":"$1100" 
     } 
    } 
} 

Есть ли способ, чтобы получить длину «purchase_record» для каждой записи?

+0

Вы правы. Исправленный. – cytsunny

+1

Не без использования карты/уменьшения. Вы считали создание 'purchase_record' массива? – JohnnyHK

ответ

1

Вы должны рассмотреть возможность изменения структуры своих документов, создавая purchase_record массив, как указано @JohnnyHK. Лучший способ сделать это - использовать операции "bulk".

var bulk = db.xx.initializeUnorderedBulkOp(); 
var count = 0; 
db.xx.find().forEach(function(doc) { 
    var purchase_record = doc.purchase_record; 
    var newRecord = []; 
    for(var key in purchase_record) { 
     if(Object.prototype.hasOwnProperty.call(purchase_record, key)) 
      newRecord.push({'units': key, 'price': purchase_record[key]}); 
    } 
    bulk.find({ '_id': doc._id }).updateOne({ 
     '$set': { 'purchase_record': newRecord } }); 
    count++; 
    if(count % 300 === 0) { 
     // Execute per 300 operations 
     bulk.execute(); 
     bulk = db.xx.initializeUnorderedBulkOp(); 
    } 
}) 

// Clean up queues 
if (count > 0) bulk.execute(); 

После этой операции ваши документы выглядеть следующим образом:

{ 
     "_id" : ObjectId("565aad654036f6520c25a9bb"), 
     "name" : "pencil", 
     "purchase_record" : [ 
       { 
         "units" : "1", 
         "price" : "$900" 
       }, 
       { 
         "units" : "2", 
         "price" : "$1000" 
       }, 
       { 
         "units" : "3", 
         "price" : "$1100" 
       }, 
       { 
         "units" : "4", 
         "price" : "$1200" 
       } 
     ] 
} 
{ 
     "_id" : ObjectId("565aad654036f6520c25a9bc"), 
     "name" : "pen", 
     "purchase_record" : [ 
       { 
         "units" : "1", 
         "price" : "$1000" 
       }, 
       { 
         "units" : "2", 
         "price" : "$1200" 
       }, 
       { 
         "units" : "3", 
         "price" : "$900" 
       }, 
       { 
         "units" : "4", 
         "price" : "$1100" 
       }, 
       { 
         "units" : "5", 
         "price" : "$1100" 
       } 
     ] 
} 

Теперь вы можете использовать метод .aggregate(), который обеспечивает доступ к трубопроводу агрегации в $project документов и вернуть " purchase_record "$size

db.xx.aggregate([ 
    { '$project': { 
     '_id': 0, 
     'name': 1, 
     'size_purchase_record': { '$size': '$purchase_record' } 
    }} 
]) 

Который возвращает:

{ "name" : "pencil", "size_purchase_record" : 4 } 
{ "name" : "pen", "size_purchase_record" : 5 } 

Вы всегда можете добавить поле «purchase_record» в результате использования: 'purchase_record': 1


С вашей текущей структуры документа вы можете использовать метод mapReduce, чтобы сделать это:

var map = function() { 
    var records = []; 
    for(var key in this.purchase_record) { 
     if(Object.prototype.hasOwnProperty.call(this.purchase_record, key)) 
      records.push(key); 
    } 
    var recordsLen = records.length; 
    emit(this.name, recordsLen); 
}; 
var reduce = function(key, values) { return values; }; 
db.xx.mapReduce(map, reduce, { out: { inline: 1 } }); 

Который возвращает:

{ 
     "results" : [ 
       { 
         "_id" : "pen", 
         "value" : 5 
       }, 
       { 
         "_id" : "pencil", 
         "value" : 4 
       } 
     ], 
     "timeMillis" : 1, 
     "counts" : { 
       "input" : 2, 
       "emit" : 2, 
       "reduce" : 0, 
       "output" : 2 
     }, 
     "ok" : 1 
} 

Или метод .map, который неэффективен, потому что это клиентская сторона.

db.xx.find().map(function(doc) { 
    return { 
     'name': doc.name, 
     'purchase_record_len': Object.keys(doc.purchase_record).length 
    }; 
}) 

Что дает:

[ 
     { 
       "name" : "pencil", 
       "purchase_record_len" : 4 
     }, 
     { 
       "name" : "pen", 
       "purchase_record_len" : 5 
     } 
] 
Смежные вопросы