Как я могу использовать Mongoose на основе _id?

Когда я делаю это:

client_id = req.param("client_id") ? null
client =
  name: req.param "clientName"
  status: 'active'

Client.update {_id: client_id}, client, {upsert: true}, (err, updRes) ->
  if err
    res.json
      error: "Couldn't create client"
  else
    res.json client

Будет создана новая запись клиента, за исключением поля null _id. Я предполагаю, что это связано с тем, что часть вставки upsert обращается к query для создания документа. Как сделать так, чтобы если ни один документ не найден, то вставлялся новый ObjectId?


person Shamoon    schedule 13.12.2011    source источник


Ответы (2)


Не уверен, что вы уже разобрались с этим, но на случай, если вы не хотите столкнуться с проблемами с уникальными ключевыми ограничениями, такими как Мустафа, упомянутый выше, я сделал это с помощью findByIdAndUpdate:

// require mongoose

client_id = req.param("client_id") ? new mongoose.Types.ObjectId
client =
  name: req.param "clientName"
  status: 'active'

Client.findByIdAndUpdate client_id, client, {upsert: true}, (err, updRes) ->
  if err
    res.json
      error: "Couldn't create client"
  else
    res.json client

Я никогда не писал CoffeeScript, поэтому простите меня, если что-то в этом синтаксисе неправильно, но я думаю, должно быть достаточно очевидно, что я пытаюсь сделать.

Следует отметить, что вам нужно убедиться, что client_id не является ни пустой строкой (поскольку это вызовет ошибку «Invalid ObjectID»), ни нулевым значением (потому что мангуст, похоже, выводит идентификатор нового документа из того, который вы запрашиваете). В этом случае я создаю новый ObjectId, что приведет к пропущенному запросу, и, следовательно, создам новый документ с этим идентификатором, поскольку я передаю {upsert: true}.

Кажется, это решило проблему для меня.

person Hannes Johansson    schedule 23.10.2012
comment
После Mongoose v 4.0 вам необходимо явно установить для параметра new значение true, поскольку до версии 4.0 значение по умолчанию было true, а после версии 4.0 — false. Ссылка этот вопрос о переполнении стека и эти примечания к выпуску. - person steampowered; 02.08.2015

Все, что вам нужно сделать с Mongoose, это вызвать save на клиенте, Mongoose самостоятельно определит, является ли это обновлением или вставкой:

client_id = req.param("client_id") ? null
client_data =
  name: req.param "clientName"
  status: 'active'
  _id: client_id

client = new Client(client_data)
client.save (err) ->
  if err
    res.json
      error: "Couldn't save client"
  else
    res.json client

Примечание. Клиент — модель Mongoose.

person alessioalex    schedule 13.12.2011
comment
Значит, больше не нужно апсертов? - person Shamoon; 13.12.2011
comment
Я могу сказать вам, что я действительно использовал это в своем коде, как для вставок, так и для обновления, и это работает, поэтому нет необходимости в upserts. Благослови Мангуста ODM :) - person alessioalex; 13.12.2011
comment
Если client_id равен нулю, будет ли это сохранено с новым _id? - person Shamoon; 13.12.2011
comment
Можете ли вы объяснить больше, @Mustafa? - person wprl; 05.07.2012
comment
подтвердил, что это не удается в индексированном поле. ссылка: groups.google.com/forum/? fromgroups=#!topic/mongoose-orm/ - person blu; 30.08.2012
comment
Похоже, это уже не проблема? Я могу получить неудачный уникальный. - person binarygiant; 19.06.2013
comment
Не обращайте внимания, не так, как я думал - person binarygiant; 22.06.2013