Вопрос по mongodb – Mongodb upsert встроенный документ

5

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

{
  "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}
}

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

Ваш Ответ

1   ответ
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

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

Похожие вопросы