mongodb микро-оптимизация пакетных вставок? или это важная оптимизация? - PullRequest
1 голос
/ 03 февраля 2012

предпосылка : операторы обновления безвредны, поскольку драйвер по умолчанию работает в одном направлении (если 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, поскольку оператор $ требует заполнения в поле запроса части запроса обновления.амирит?иамрить?

Если это лучший способ сделать что-то, могу ли я проявить творческий подход к своему коду и сходить с ума от операций обновления?

edit: new form

В моей логике произошла ошибка, спасибо Гейтс.Тем не менее, я хочу свернуть обновления, если это возможно: 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 Ответ

1 голос
/ 03 февраля 2012

Итак, первое, что нужно отметить, это то, что позиционный оператор $ немного схематичен.У него много «ловушек»: он плохо работает с апперсами, он влияет только на первый истинный матч и т. Д.

Чтобы понять «сворачивание» №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}  
    ] 
}

Это правильно?Это первый документ законен?( семантически правильно )?В зависимости от ответов это может быть проблемой структуры документа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...