2014-01-30 2 views
6

У меня есть документ со структурой, аналогичной этой

{ 
    "brand": "BMW", 
    "models": ["320","545"] 
} 

модели должно быть уникальным, и я использую следующий запрос при добавлении новых элементов,

db.cars.update(
    {brand:'BMW'}, 
    { 
     $addToSet: { 
      models: '750' 
     } 
    }, 
    {upsert:true} 
); 

Это дало бы

{ 
    "brand": "BMW", 
    "models": ["320","545","750"] 
} 

Вопрос:

Как можно ограничить общее количество моделей товаров? Скажем, я хочу сохранить только последние 3 добавленные модели. Так что, если я вставляю новую модель «135», я бы в конечном итоге с

{ 
    "brand": "BMW", 
    "models": ["545","750","135"] 
} 

Я прочитал о модификатором $slice однако, как представляется, будет доступна только при использовании $push и не $addToSet

ответ

5

Интересный вопрос, как это на самом деле предмет bug, который был поднят для request. Что касается запроса, я бы не задерживал дыхание, когда добавлял это поведение.

Это ошибка в том, что вы могли бы на самом деле выполнить следующее:

db.cars.update(
    {brand:'BMW'}, 
    { $addToSet: { models: { $each: ['200'], $slice: 3 } } }, 
    {upsert: true} 
) 

и addToSet бы просто работать, пока игнорируя модификатор, или предупреждение. Но, конечно, теперь у вас будет четыре элемента в вашем массиве.

Замечания от технического директора не менее указывают на конфликт в терминах.

Таким образом, единственное, что я могу придумать, - сначала проверить элемент в массиве, используя $elemMatch в поиске, и если оба документа существуют, а поиск $ elemMatch не является истинным, тогда обновите с помощью обычного $ push и slice , В противном случае вставьте новый документ или оставьте его в покое

db.cars.update(
    {brand:'BMW'}, 
    {$push: { models: { $each: ['750'], $slice: -3 } }} 
) 

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

+1

Благодарю вас за ответ, я использовал монго только пару дней и думал, что что-то подобное будет тривиально. Из ссылок, которые я собираю, кажется, что существует определенное различие между массивами и множествами, о которых я не знал. – lostsource

+1

[SERVER-8512: поддержка $ slice/sort в $ addToSet] (https://jira.mongodb.org/browse/SERVER-8512) «запрос», который вы упоминаете, уже закрыт, так как «не будет исправляться» так определенно не задерживайте это дыхание ;-). Наборы в настоящее время реализованы как массивы, но не имеет смысла смешивать модификатор '$ addToSet' с механикой массива' $ slice'. Наборы следует считать неупорядоченными. – Stennie