2012-04-18 6 views
5

У меня есть документ в день на метр. Как я могу добавить еще один поддокумент в массив данных и создать весь документ, если он не существует?Mongodb upsert embedded document

 
{ 
    "key": "20120418_123456789", 
    "data":[ 
    { 
    "Meter": 123456789, 
    "Dt": ISODate("2011-12-29T16:00:00.0Z"), 
    "Energy": 25, 
    "PMin": 11, 
    "PMax": 16 
    } 
    ], 
    "config": {"someparam": 4.5} 
} 

Могу ли я использовать upsert для этой цели?

Результат будет, если документ существует:

 
{ 
    "key": "20120418_123456789", 
    "data":[ 
    { 
    "Meter": 123456789, 
    "Dt": ISODate("2011-12-29T16:00:00.0Z"), 
    "Energy": 25, 
    "PMin": 11, 
    "PMax": 16 
    }, 
    { 
    "Meter": 123456789, 
    "Dt": ISODate("2011-12-29T16:15:00.0Z"), 
    "Energy": 22, 
    "PMin": 13, 
    "PMax": 17 
    } 
    ], 
    "config": {"someparam": 4.5} 
} 

Заранее спасибо

ответ

9

Я думаю, что вы хотите, это команда $ addToSet - что будет толкать элемент в массив, только если он не уже существует. Я упростил ваш пример немного для краткости:

db.meters.findOne() 
{ 
    "_id" : ObjectId("4f8e95a718bc9c7da1e6511a"), 
    "config" : { 
     "someparam" : 4.5 
    }, 
    "data" : [ 
     { 
      "Meter" : 123456789, 
     } 
    ], 
    "key" : "20120418_123456789" 
} 

Теперь запустите:

db.meters.update({"key" : "20120418_123456789"}, {"$addToSet": {"data" : {"Meter" : 1234}}}) 

И мы получаем обновленную версию:

db.meters.findOne() 
{ 
    "_id" : ObjectId("4f8e95a718bc9c7da1e6511a"), 
    "config" : { 
     "someparam" : 4.5 
    }, 
    "data" : [ 
     { 
      "Meter" : 123456789, 
     }, 
     { 
      "Meter" : 1234 
     } 
    ], 
    "key" : "20120418_123456789" 
} 

Выполнить ту же команду еще раз, и результат не меняется.

Примечание: вы, вероятно, будете выращивать эти документы, особенно если это поле неограниченно и вызывает частые (относительно дорогостоящие) перемещения путем обновления таким образом - вы должны посмотреть здесь на идеи о том, как смягчить это:

http://www.mongodb.org/display/DOCS/Padding+Factor#PaddingFactor-ManualPadding

+0

я должен сделать 400000 addToSet в день ... 96 данные за каждый документ. Кажется, он медленный ... Есть ли другие способы сделать это? – hotips

+0

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