Основная проблема здесь в том, что ваш $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
, чтобы облегчить точное совпадение.
Поэтому ваши два положения о внесении этого действительного для обновления более осколков является либо:
Включить «диапазон» над возможными значениями ключа шарда с критериями запроса. Я не знаю вашего ключа осколка, поэтому я не могу дать образец. Но в основном:
{
"shardKey": { "$gt": minShardKey, "$lt": maxShardKey },
"$or": [
{ "a": 2, "b": 3 },
{ "a": 3, "b": 2 }
]
}
В качестве условия запроса, где minShardkey
и maxShardKey
относятся к минимуму и максимально возможных значений на этой клавише в диапазоне (от также гипотетического поля «shardKey») для того, чтобы менеджер подумайте, что вы действительно собираетесь искать по всем осколкам.
Включить «мульти» вариант в обновлении, как так:
db.collection.update(
{ "$or":[
{ "a": 2, "b": 3 },
{ "a": 3, "b": 2 }
]},
{ "$set": { "x":5 } },
{ "multi": true }
)
Что делает выбор «возможно» соответствовать более чем один, и, следовательно, действует для поиска над осколками без необходимости целевого ключа осколка ,
В любом случае, логика выполняется в том, что вы по крайней мере, «намереваться», чтобы найти условия по осколкам, чтобы найти что-то или «вещи», которые соответствуют условиям вы дали.
В качестве дополнительной записке, то также считают, что «upsert» действия имеют аналогичные ограничения, и что общий принцип заключается в том, что ключ осколок необходимо решить, othewise операции в недействителен, так как там потребности быть некоторые признаки из которых осколок для вставки новых данных.
Благодарим вас за ответ так быстро.Я решил включить опцию «multi» в обновление, даже если операции с несколькими обновлениями всегда являются вещательными операциями. – mcanzerini
@mcanzerini Это в основном «стоимость» здесь, если у вас нет определенного представления о «возможном» условии для shardKey, в котором это будет содержаться, чтобы поэтому нацелить его на определенный осколок. Действующий тип «вентилятор на запись» действителен, но он должен уважать границы в одном из возможных способов. Хороший вопрос BTW. Это то, о чем многие люди не замечают. –