mongodb обновить сериализованный объект json с помощью python

Это проблема часто обновляемой структуры подсловаря. Компромисс между CPU и IO.

В памяти есть вложенная структура данных dict. Код 1:

domain={}
domain["www.xx.com"]={}
domain["www.xx.com"]["192.105.0.1"]={}
domain["www.xx.com"]["192.105.0.1"]["TTLS"]=Set([20,80,3000])
domain["www.xx.com"]["192.105.0.1"]["FIRST_SEEM"]=1379484935.460281
domain["www.xx.com"]["192.105.0.1"]["LAST_SEEN"]=1379484945.46077

domain["www.xx.com"]["192.105.0.2"]={}
domain["www.xx.com"]["192.105.0.2"]["TTLS"]=Set([70,90,2000])
domain["www.xx.com"]["192.105.0.2"]["FIRST_SEEM"]=13794674935.460281
domain["www.xx.com"]["192.105.0.2"]["LAST_SEEN"]=1379674945.46077

Затем сериализуйте часть Set. Код 2:

domain["www.xx.com"]["192.105.0.1"]["TTLS"]=list(domain["www.xx.com"]["192.105.0.1"]["TTLS"])
domain["www.xx.com"]["192.105.0.2"]["TTLS"]=list(domain["www.xx.com"]["192.105.0.2"]["TTLS"])

Затем выгрузите эту структуру в mongodb, например, код 3:

db.myCollection.insert({"_id":"www.xx.com", "IPS":json.dumps(domain["www.xx.com"])})

Товар часто обновляется. Настал новый день, программа сгенерирует в памяти новый элемент dict о «www.xx.com», затем обновит этот элемент прежней информацией в mongodb. да, наоборот, для более простого обновления монго. Здесь загрузка json возвращает словарь, точно такой же, как и тот, который был сброшен (кроме набора). Код 4

mongo_dict=json.loads(db.myCollection.find_one({"_id":"www.xx.com"}))
update_domain_with_mongo_dict(mongo_dict)

Итак, в конце этого дня программа просто сбрасывает всю память домена ["www.xx.com"] на монго. это экономит работу по обновлению документа, упрощает ввод-вывод, оставляя грязную работу программе python. (Я читал много жалоб на плохую возможность обновления поддокументов в монго.) Код 5

db.myCollection.update({"_id":"www.xx.com"},{"$set":{"IPS":json.dumps(domain["www.xx.com"])}})

Однако, похоже, многим обновление бессмысленно. Даже если обновление не происходит или происходит небольшое обновление, программе придется восстановить элемент dict в mongodb. Относительно этого, IO слишком большой. Вот проблема, мне нужно обновить поддокумент отдельно, со многими циклами for и проверкой новых обновлений. Итак, json сбрасывает/загружает, до свидания.

тогда уточненный объект mongo и коды могут выглядеть так: Код 6

{
    "_id":"www.xx.com"
    "IPS":[
        {
            "IP":"192.168.0.1"
            "TTLS":[20, 80, 3000]
            "FIRST_SEEN":1379484935.460281
            "LAST_SEEN":1379484945.46077
        }
        {
            "IP":"192.168.0.2"
            "TTLS":[70, 90, 2000]
            "FIRST_SEEN":13794674935.460281
            "LAST_SEEN":1379674945.46077
        }
    ]
}
db.update({"_id":"www.xx.com"}, 'IPS'.0.'FIRST_SEEN':1379674945.46077)

однако для этого типа обновления требуется индекс «0», это определяется ключом: ip. В этой структуре я отказываюсь от дампов/загрузок json, что означает отказ от dict. Чтобы получить индекс, цикл for неизбежен. Это может сэкономить ввод-вывод, но ЦП будет плакать.

Итак, ребята, вы слишком много читали, каков ваш выбор? любое фантастическое решение, удивите меня. Дайте мне знать, если я что-то пропущу. Спасибо.


person kthinker    schedule 03.03.2014    source источник


Ответы (1)


Вам не нужно отслеживать все это в своем приложении. Монго довольно крепкий

При добавлении новых вещей вы хотите использовать $push

db.myCollection.update(
    {"_id":"www.xx.com"},
    {"$push":{"IPS": <new to be added>}}
)

Это означает, что вы можете добавлять каждый элемент отдельно, а не добавлять их все сразу. Но самое главное, это позволяет вам расти, не заботясь о том, что там внутри. Вы также можете добавить $each, чтобы сделать это в наборах, если вам нужно.

Если вы хотите что-то обновить, а не отслеживать индекс, найдите элемент по значению в массиве:

db.myCollection.update(
    {"_id":"www.xx.com", "IPS.IP" <IP Entry>},
    {"$set":{"IPS.$.LAST_SEEN": <new date value>}}
)

Таким образом, использование позиционного оператора гарантирует, что обновление произойдет в позиции совпавшего «IP».

Если вы действительно беспокоитесь о задержке, то, возможно, ваш вариант использования позволит вам вернуться к написать беспокойство. Вы можете прочитать эту ссылку, чтобы понять, что вам может сойти с рук, чтобы немного ускорить запись ответов.

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

Так что обязательно держите кеш и не пишите каждое обновление. Но когда вы пишете, сбрасывайте его, и, используя такие операции, вы получаете ценность от своих записей.

Потратьте некоторое время на просмотр полного справочника по операторам.

person Neil Lunn    schedule 03.03.2014
comment
спасибо, Нил, $push добавляет указанное значение в массив. но в коде 4 есть не только добавление, но и изменение. Мне нужен способ эффективно объединить домен [www.xx.com][a] с mongo_db[www.xx.com][a]. Дамп всего домена[www.xx.com] на монго, как я уже сказал, слишком много бессмысленного ввода-вывода. даже с $push. кстати, вы имеете в виду $push и $each, верно? - person kthinker; 03.03.2014
comment
@forgarfield Да, я понимаю. Ваш вопрос не очень ясен и на самом деле задает слишком много вопросов. Мы встретили толчок, верно? Итак, вы знаете, какое значение из списка вы хотите обновить. Помимо индекса, что мы идем дальше. IP? Будет ли это уникальным в этом списке для каждого из документов вашего сайта? - person Neil Lunn; 03.03.2014
comment
да, IP уникален в этом списке. Вы имеете в виду, что я могу обновить список с временной сложностью O (1)? - person kthinker; 03.03.2014
comment
@forgarfield Я хотел, чтобы вам не нужно было хранить эту сложность в приложении. Я надеюсь, что дополнительные примечания указывают на то, что можно использовать, чтобы сбить это, или просто принять отправку всего прямо в монго, с некоторыми изменениями. - person Neil Lunn; 03.03.2014
comment
Спасибо. потому что я должен убедиться, что элемент IPS.IP находится в монго, я отслеживаю индекс, как вы упомянули. например db.Mycollectoin.update({_id:www.xx.com},{$set:{IPS.+str(index)+.LAST_SEEN: ‹новое значение даты›}}). с индексом обновление может быть немного быстрее. Кажется, сейчас работает. если не хорошо, я применяю кеш позже. спасибо за ссылку - person kthinker; 04.03.2014