Как я могу обновить вложенный документ в MongoDB?

Код, созданный в Mongoose для обновления вложенного документа, не работал. Поэтому я попытался обновить вложенный документ в Mongo Shell.
Это документ (местоположение) и вложенный документ (обзор):

{
"_id" : ObjectId("56d8c73314fbc7e702cfb8c4"),
"name" : "Costly",
"address" : "150, Super Street",
"coords" : [
    -0.9630884,
    51.451041
],
"reviews" : [
    {
        "author" : "kyle riggen1",
        "_id" : ObjectId("56d8de74cc7f953efd8455d9"),
        "rating" : 4,
        "timestamp" : ISODate("2015-06-01T06:00:00Z"),
        "reviewText" : "will the ID work?"
    }
],
"rating" : 0,
"__v" : 2

}

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

update({ 
       _id: "56d8c73314fbc7e702cfb8c4", 
       "reviews._id": ObjectId("56d8de74cc7f953efd8455d9")
   },{
       $set: {"reviews.$.rating": 1}
   }, false, true
);

Это вернуло ошибку «обновление не определено», как показано:

2016-03-03T22:52:44.445-0700 E QUERY    [thread1] ReferenceError: update is not defined :
@(shell):1:1

Я думаю, это потому, что команда не начиналась с db.locations.update()

Документация MongoDB использовала этот формат:

db.locations.update(
   {
     _id: "56d8c73314fbc7e702cfb8c4",
     review: { $elemMatch: { author: "kyle riggen1" } }
   },
   { $set: { "location.$.rating" : 1 } }
)

Это возвращает действительное обновление, но на самом деле обновление не произошло, как показано:

WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })

В этом вопросе использовался следующий формат:

db.locations.update({
    _id: "56d8c73314fbc7e702cfb8c4",
    'review.author': 'kyle riggen1'
  },
  { $set: { 'review.$.rating': 1 }}
)

Это возвращает то же самое, что и документация MongoDB, как показано здесь:

WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })

Итак, эти запросы, я думаю, работают, но мои данные не обновляются. Возможно, мои данные будут проиндексированы неправильно? Фактическое местоположение может быть обновлено даже через API Mongoose.


person KyleRiggen    schedule 04.03.2016    source источник
comment
Хотели бы вы еще раз попробовать выбрать заголовок, который никого не оскорбит или иным образом не смутит вас, когда люди дадут простое объяснение? И, конечно же, это объяснение ObjectId("56d8c73314fbc7e702cfb8c4"). Ой, вы забыли бросить свою строку.   -  person Blakes Seven    schedule 04.03.2016
comment
@BlakesSeven исправил заголовок на более подходящий вопрос. ObjectId() появляется только в моей оболочке mongo. API выдает идентификатор без него. Я отредактировал свой вопрос, чтобы отразить это.   -  person KyleRiggen    schedule 04.03.2016
comment
Какой API? Все ваши примеры (и каждая ошибка и ответ) выдаются из оболочки MongoDB. Значения, которые вы передаете _id в запросе, должны быть ObjectId, иначе они не будут совпадать. Это именно то, что происходит здесь. Только что-то вроде mongoose будет автоматически отображать строку как тип схемы для вас, но вы не выполняете ни один из своих образцов в мангусте.   -  person Blakes Seven    schedule 04.03.2016
comment
@BlakesSeven, я думаю, можно попробовать   -  person KyleRiggen    schedule 04.03.2016
comment
@BlakesSeven И это сработало! Не могли бы вы представить ответ, чтобы я мог отдать вам должное на мой глупый вопрос?   -  person KyleRiggen    schedule 04.03.2016
comment
На самом деле я уже отметил его для закрытия, поскольку довольно явное упущение приведения к ObjectId является довольно простой ошибкой, и уже зачислено на ответы и вопросы, представленные много лет назад. В следующий раз обратите внимание.   -  person Blakes Seven    schedule 04.03.2016


Ответы (2)


Вы можете сделать это с помощью $push или $addToSet.

db.col.update(
        { name: 'reviews', 'list.id': 2 }, 
        {$push: {'list.$.items': {id: 5, name: 'item5'}}}
    )

См. ссылку из руководства mongodb.

https://docs.mongodb.org/manual/reference/operator/update/push/

person Istiak Morsalin    schedule 04.03.2016

Пожалуйста, знайте db.collection.update( criteria, objNew, upsert, multi )

  1. criteria: условие совпадения
  2. objNew: обновить содержимое
  3. upsert: true or false
    • true : if not existed, insert it
    • false : если не существует, не вставлять
  4. multi: true or false
    • true : update all matched documents
    • false : обновить только первый соответствующий документ
person Superman    schedule 25.10.2016
comment
Извините, это мой первый ответ. Я не знаком с этим форумом. Я могу ознакомиться с ним как можно скорее. - person Superman; 23.11.2016