Обновить объект внутри массива объекта в документе mon goose с помощью проекции или выберите - PullRequest
0 голосов
/ 25 апреля 2020

Я пытаюсь обновить объект внутри документа

Документ: Кошки

{
        "_id": "5e5cb512e90bd40017385305",
        "type": "cat"
        "history": [
          {
            "id": "randomID",
            "content": "xyz",
          },
          {
            "id": "randomID2",
            "content": "abc",
          }
        ]
}

Код для выбора и обновления объекта внутри массива истории:

const editHistory = async (_, { input }, ctx) => {
  let query = { _id: input.catId, "history.id": input.historyId };
  let update = { $set: { "history.$": input.history } };
  let options = {
    new: true,
    fields: { history: { $elemMatch: { id: "randomID" } } }
  };

  let cat = await ctx.models.cats.findOneAndUpdate(query, update, options);

  return cat;
};

Входные данные имеют следующие значения

input: {
catId: "5e5cb512e90bd40017385305",
historyId: "randomID",
history: {
id: "randomID",
content: "new content"
}}

Я пытался использовать проекцию, я использовал select, изменил его на поле, найденное в документации mon goose. Я все еще не мог обновить значения. Что-то не так с тем, как я запрашиваю или выбираю подполе.

1 Ответ

1 голос
/ 28 апреля 2020

Нашли решение для этого, пройдя более подробную информацию об операторе ($ set) и опции (new, fields).

Вопрос:

const editHistory = async (_, { input }, ctx) => {
  let query = { _id: input.catId, "history.id": input.historyId };
  let update = { $set: { "history.$": input.history } };
  let options = {
    // using new option would return the new document
    new: true, 
    /* using fields option would select the based on the given key, but using new: 
       true with fields will throw error: 'cannot use a positional projection and 
   return the new document'
   */
    fields: { history: { $elemMatch: { id: "randomID" } } } 
  };

  let cat = await ctx.models.cats.findOneAndUpdate(query, update, options);

  return cat;
};

Этот пост ниже отвечает на этот вопрос для * error: «не может использовать позиционную проекцию и вернуть новый документ».

{ ссылка }

Окончательное решение:

const editHistory = async (_, { input }, ctx) => {
  let query = { _id: input.catId, "history.id": input.historyId };
  let update = { $set: { "history.$": input.history } };
  let options = {
    new: true
  };

  let cat = await ctx.models.cats.findOneAndUpdate(query, update, options);

  return cat;
};

Опция удаления поля, поскольку мне не требуется неизмененный выбор перед модификацией atomi c, решает вопрос.

...