Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

160
Visualizações
Mongodb updating nested array of objects

I need to update a field nested in my User document, that contains an array of part objects, to add new parts. One part object looks like this:

{
  partId: 871838,
  partNum: '87087',
  partName: 'Brick Special 1 x 1 with Stud on 1 Side',
  colorId: 0,
  colorName: 'Black',
  quantity: 10,
  partImg: 'https:...'
}

I want to add the part to the array, but only if user doesn't already own it. I tried using $addToSet, like so:

await User.updateOne(
    { username: username },
    { $addToSet: { parts: { $each: req.body.parts } } }
  );

but that won't work, since sometimes the part is the same, but the quantity varies, and that is enough to treat is as a different part, so it gets added. Is there a way to specify by which value to determine if the object already exists in an array?

EDIT: so, I found this in the docs :

you cannot specify that MongoDB compare only a subset of the fields in the document to determine whether the document is a duplicate of an existing array element

So that means that $addToSet is no good for my case... Now I have no idea what to do.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

I'm posting an answer, since I managed to get the result that I wanted, and I'd like some feedback. It works fine, but feels brute force and kinda hacky:

  const incomingParts = req.body.parts;
  const _ownedParts = await User.findOne(
    { username: username },
    { parts: 1, _id: 0 }
  );

  let ownedParts: IPart[] = [];
  const newParts: IPart[] = [];

  //if statement for TS
  if (_ownedParts) {
    ownedParts = _ownedParts.parts;
  }

  let partsToAdd;
  if (ownedParts.length === 0) {
    //if the user owns no parts, just add the whole lot
    partsToAdd = [...req.body.parts];
  } else {
    incomingParts.forEach((incoming: IPart) => {
      const ownedIdx = ownedParts.findIndex((owned: IPart) => {
        return incoming.partId === owned.partId;
      });

      if (ownedIdx !== -1) {
        ownedParts[ownedIdx].quantity += incoming.quantity;
      } else {
        newParts.push(incoming);
      }
    });
    partsToAdd = [...ownedParts, ...newParts];
  }

  await User.updateOne(
    { username: username },
    { $set: { parts: partsToAdd }, $push: { sets: setNum } }
  );

If there is a way using mongodb operators or aggregate, I'd love to see that.

over 4 years ago · Santiago Trujillo Relatório

0

If I understand it correctly you want to change a specific field if the part exists. After you get the checks you may refer to this:

await User.updateOne(
    { username: username },
    { $set:  { "parts.0.partNum": 234234 }
  );

That assuming you know the index of the specific part. You can use this for reference: https://docs.mongodb.com/manual/reference/operator/update/set/

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda