2015-08-21 2 views
1

Я выполнил обновление в sharded среды, как:

db.collection.update({$or:[{a:2,b:3},{a:3,b:2}]},{$set:{x:5}}) 

Но я получил сообщение об ошибке:

update { q: { $or: [ {a:2,b:3},{a:3,b:2} ] }, u: {$set:{x:5}}, multi: false, upsert: false } does not contain _id or shard key for pattern { a: 1.0, b: 1.0 } 

Как я выполнить этот вид обновления с $ или предикат на клавише осколка?

Благодаря

ответ

1

Основная проблема здесь в том, что ваш $or состояние не очень много смысла без «мульти» параметра обновления заявление. По крайней мере, условная логика осколков думает так, даже если ваше намерение состояло в том, чтобы соответствовать единственному документу.

В «умах» диспетчера строгания, который живет с маршрутизатором mongos, ожидание состоит в том, что вы либо нацеливаетесь на единичный осколок или диапазон ключей, либо вы запрашиваете доступ к возможному разнообразию или осколкам.

Вот actual code обработки этого для справки:

// Validate that single (non-multi) sharded updates are targeted by shard key or _id 
if (!updateDoc.getMulti() && shardKey.isEmpty() && !isExactIdQuery(updateDoc.getQuery())) { 
    return Status(ErrorCodes::ShardKeyNotFound, 
        stream() << "update " << updateDoc.toBSON() 
          << " does not contain _id or shard key for pattern " 
          << _manager->getShardKeyPattern().toString()); 
} 

Так как вы должны ясно видеть в «если» состоянии, ожидание здесь является то, что есть либо определение «шард ключ» в запрос или, по крайней мере, точный _id, чтобы облегчить точное совпадение.

Поэтому ваши два положения о внесении этого действительного для обновления более осколков является либо:

  1. Включить «диапазон» над возможными значениями ключа шарда с критериями запроса. Я не знаю вашего ключа осколка, поэтому я не могу дать образец. Но в основном:

    { 
        "shardKey": { "$gt": minShardKey, "$lt": maxShardKey }, 
        "$or": [ 
         { "a": 2, "b": 3 }, 
         { "a": 3, "b": 2 } 
        ] 
    } 
    

    В качестве условия запроса, где minShardkey и maxShardKey относятся к минимуму и максимально возможных значений на этой клавише в диапазоне (от также гипотетического поля «shardKey») для того, чтобы менеджер подумайте, что вы действительно собираетесь искать по всем осколкам.

  2. Включить «мульти» вариант в обновлении, как так:

    db.collection.update(
        { "$or":[ 
         { "a": 2, "b": 3 }, 
         { "a": 3, "b": 2 } 
        ]}, 
        { "$set": { "x":5 } }, 
        { "multi": true } 
    ) 
    

    Что делает выбор «возможно» соответствовать более чем один, и, следовательно, действует для поиска над осколками без необходимости целевого ключа осколка ,

В любом случае, логика выполняется в том, что вы по крайней мере, «намереваться», чтобы найти условия по осколкам, чтобы найти что-то или «вещи», которые соответствуют условиям вы дали.

В качестве дополнительной записке, то также считают, что «upsert» действия имеют аналогичные ограничения, и что общий принцип заключается в том, что ключ осколок необходимо решить, othewise операции в недействителен, так как там потребности быть некоторые признаки из которых осколок для вставки новых данных.

+0

Благодарим вас за ответ так быстро.Я решил включить опцию «multi» в обновление, даже если операции с несколькими обновлениями всегда являются вещательными операциями. – mcanzerini

+0

@mcanzerini Это в основном «стоимость» здесь, если у вас нет определенного представления о «возможном» условии для shardKey, в котором это будет содержаться, чтобы поэтому нацелить его на определенный осколок. Действующий тип «вентилятор на запись» действителен, но он должен уважать границы в одном из возможных способов. Хороший вопрос BTW. Это то, о чем многие люди не замечают. –