mongodb микро-оптимизация пакетных вставок? или это важная оптимизация?
предпосылка: операторы обновления безвредны, так как драйвер по умолчанию работает в одном направлении (до тех пор, пока getLastError
не используется).
вопрос Является ли следующий фрагмент лучшим способом сделать это в mongodb для вставок большого объема? Можно ли сложить шаги 2 и 3?
редактировать: старая форма с ошибками, см. ниже
// step 1 : making sure the top-level document is present (an upsert in the real
example)
db.test.insert( { x :1} )
// step 2 : making sure the sub-document entry is present
db.test.update( { x:1 }, { "$addToSet" : { "u" : { i : 1, p : 2 } } }, false)
// step 3 : increment a integer within the subdocument document
db.test.update( { x : 1, "u.i" : 1}, { "$inc" : { "u.$.c" : 1 } },false)
У меня такое ощущение, что выхода из операции 3 нет, так как$
Оператор требует заполнения в поле запроса части запроса обновления. амирит? иамрить?
Если это лучший способ сделать что-то, могу ли я проявить творческий подход в своем коде и сходить с ума от операций обновления?
редактировать: новая форма
В моей логике была ошибка, спасибо Гейтсу. Еще хочу свернуть обновления, если это возможно:D
// make sure the top-level entry exists and increase the incidence counter
db.test.update( { x : 1 }, { $inc : { i : 1 } }, true ) --1
// implicetly creates the array
db.test.update( { x : 1 , u : { $not : { $elemMatch : { i : 1 } } } } ,
{ $push : { u : { i : 1 , p :2 , c:0} } }) -- 2
db.test.update( { x :1 , "u.i" : 1}, { $inc : { "u.$.c" : 1 } },false) --3
заметки: $addToSet
в этом случае бесполезен, так как он выполняет поэлементное соответствие, нет способа выразить, какие элементы в массиве могут быть mutable
как в C++ OO язык побитового сравнения
вопрос бессмысленный Модель данных неверна. Пожалуйста, проголосуйте, чтобы закрыть (OP).
1 ответ
Итак, первое, что следует отметить, что $
позиционный оператор немного отрывочен. У него много "ловушек": он плохо играет с апперсами, он влияет только на первый настоящий матч и т. Д.
Чтобы понять "сворачивание" #2 и #3, вам нужно посмотреть на вывод ваших команд:
db.test.insert( { x :1} )
{ x:1 } // DB value
db.test.update( { x:1 }, { "$addToSet" : { "u" : { i : 1, p : 2 } } }, false)
{ x:1, u: [ {i:1,p;2} ] } // DB value
db.test.update( { x : 1, "u.i" : 1}, { "$inc" : { "u.$.c" : 1 } },false)
{ x:1, u: [ {i:1,p:2,c:1} ] } // DB value
Исходя из предоставленной вами последовательности, все это можно свернуть в одно обновление.
Если вы хотите собрать только № 2 и № 3, значит, вы беспокоитесь о соответствии 'u.i':1
с u.$.c
, Но здесь есть некоторые крайние случаи, которые вы должны уточнить.
Пусть ваш начальный документ будет следующим:
{
x:1,
u: [
{i:1, p:2},
{i:1, p:3}
]
}
Что вы ожидаете от запуска обновления № 3?
Как написано, вы получите:
{
x:1,
u: [
{i:1, p:2, c:1},
{i:1, p:3}
]
}
Это правильно? Это первый документ законен? (семантически правильно)? В зависимости от ответов, это может быть проблемой структуры документа.