findOne () retorna documento inteiro, em vez de um único objecto

votos
0

Eu estou tentando consultar esse conjunto de dados usando findOne():

{
    _id: {
        $oid: 5c1a4ba1482bf501ed20ae4b
    },
    wardrobe: {
        items: [
            {
                type: T-shirt,
                colour: Gray,
                material: Wool,
                brand: Filson,
                _id: 5c1a4b7d482bf501ed20ae4a
            },
            {
                type: T-shirt,
                colour: White,
                material: Acrylic,
                brand: H&M,
                _id: 5c1a4b7d482bf501ed20ae4a
            }
        ]
    },
    tokens: [],
    email: another@new.email,
    password: $2a$10$quEXGjbEMX.3ERdjPabIIuMIKu3zngHDl26tgRcCiIDBItSnC5jda,
    createdAt: {
        $date: 2018-12-19T13:46:09.365Z
    },
    updatedAt: {
        $date: 2018-12-19T13:47:30.123Z
    },
    __v: 2
}

Eu quero retornar um único objeto da itemsmatriz usando _Idcomo um filtro. Isto é como eu estou fazendo isso:

exports.deleteItem = (req, res, next) => {
    User.findOne({ 'wardrobe.items': { $elemMatch: { _id: 5c1a4b7d482bf501ed20ae4a,} } }, (err, item) => {
    console.log(item);
    if (err) {
        return console.log(error:  + err);
        }
        res.redirect('/wardrobe');      
    });
  };

No entanto, console.log(item)retorna a todo documento-assim:

{ wardrobe: { items: [ [Object], [Object] ] },
  tokens: [],
  _id: 5c1a4ba1482bf501ed20ae4b,
  email: 'another@new.email',
  password:
   '$2a$10$quEXGjbEMX.3ERdjPabIIuMIKu3zngHDl26tgRcCiIDBItSnC5jda',
  createdAt: 2018-12-19T13:46:09.365Z,
  updatedAt: 2018-12-19T13:47:30.123Z,
  __v: 2 }

Eu quero, eventualmente, usar isso para excluir itens individuais, então eu preciso filtrar o único objeto do subdocumento.

Publicado 19/12/2018 em 14:20
fonte usuário
Em outras línguas...                            


1 respostas

votos
1

No que diz respeito à sua pergunta: MongoDB sempre retorna o objeto completo que correspondem à sua consulta, a menos que você adicionar um especificando projeção quais campos devem ser devolvidos. Se você realmente deseja retornar apenas um objeto aninhado, você poderia usar o pipeline de agregação com o operador $ replaceRoot assim:

User.aggregate([
 // you can directly query for array fields instead of $elemMatching them
 { $match: { 'wardrobe.items._id': "5c1a4b7d482bf501ed20ae4a"}}},
 // this "lifts" the fields wardrobe up and makes it the new root
 { $replaceRoot: {newRoot: '$wardrobe'}
 // this "splits" the array into separate objects
 { $unwind: '$items'},
 // this'll remove all unwanted elements
 { $match: { 'items._id': "5c1a4b7d482bf501ed20ae4a" },
 },
])

Isso deve retornar apenas os itens desejados.

Uma nota embora: Se você pretende remover elementos de matrizes de qualquer maneira, eu prefiro sugerir que você tem um olhar para a operação de US $ tração, que pode remover um elemento de uma matriz se ele corresponde a uma certa condição:

https://docs.mongodb.com/manual/reference/operator/update/pull/

User.update(
  { 'wardrobe.items._id': "5c1a4b7d482bf501ed20ae4a"},
  { $pull: { 'wardrobe.items': {_id: "5c1a4b7d482bf501ed20ae4a"}},
  { multi: true }
)
Respondeu 19/12/2018 em 15:44
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more