MongoDB - добавление к множеству и увеличение - PullRequest
1 голос
/ 26 октября 2011

Я пытаюсь посчитать использование слов, используя MongoDB. Моя коллекция сейчас выглядит так:

{'_id':###, 'username':'Foo', words:[{'word':'foo', 'count':1}, {'word':'bar', 'count':1}]}

Когда создается новый пост, я извлекаю все новые слова в массив, но я пытаюсь выяснить, можно ли использовать массив слов и увеличить счетчик, если слово уже существует.

Например, в приведенном выше примере, если пользователь "Foo" разместил "lorem ipsum foo", я бы добавил "lorem" и "ipsum" в массив слов пользователей, но увеличил счетчик для "foo".

Возможно ли это в одном запросе? В настоящее время я использую addToSet:

'$addToSet':{'words':{'$each':word_array}}

Но это, похоже, не дает никакого способа увеличить количество слов.

Буду очень признателен за помощь:)

Ответы [ 2 ]

9 голосов
/ 26 октября 2011

Если вы хотите перейти от списка к хешу (объекту), вы можете сделать это атомарно.

Из поля docs : "$inc ... incrementsпо числовому значению, если поле присутствует в объекте, в противном случае присваивает полю значение числа.to:

words: {
  'foo': 1,
  'other_word: 2,
  ...
}

вы можете использовать операцию update с:

{ $inc: { 'words.foo': 1 } }

, которая создаст { 'foo': 1 }, если 'foo' не существует, иначе увеличьте foo.

Например:

$ db.bar.insert({ id: 1, words: {} });
$ db.bar.find({ id: 1 })
[ 
  {   ...,   "words" : {     },   "id" : 1   }
]
$ db.bar.update({ id: 1 }, { $inc: { 'words.foo': 1 } });
$ db.bar.find({ id: 1 })
[ 
  {   ...,   "id" : 1,   "words" : {   "foo" : 1   }   }
]
$ db.bar.update({ id: 1 }, { $inc: { 'words.foo': 1 } });
$ db.bar.find({ id: 1 })
[ 
  {   ...,   "id" : 1,   "words" : {   "foo" : 2   }   }
]
2 голосов
/ 26 октября 2011

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

db.users {_id:###, username:'Foo'}
db.words.counters {_id:###, word:'Word', userId: ###, count: 1}

Это позволит избежать многих проблем, таких как:

  • Максимальные размеры документов
  • Принудительное использование mongo для перемещения по вашим документам при увеличении их размера

Для обоих сценариев требуется два обновления, чтобы выполнить то, что вы хотите, что создает проблемы атомарности.Обновление каждого слова с помощью цикла word_array лучше и безопаснее (и возможно с обоими решениями).

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