findOne () возвращает весь документ, а не один объект - PullRequest
0 голосов
/ 19 декабря 2018

Я пытаюсь запросить этот набор данных, используя 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
}

Я хочу вернуть один объект из массива items, используя _Id в качестве фильтра.Вот как я это делаю:

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');      
    });
  };

Однако, console.log(item) возвращает весь документ - вот так:

{ 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 }

Я хочу в конечном итоге использовать это для удаления отдельных элементовпоэтому мне нужно отфильтровать отдельный объект из вложенного документа.

1 Ответ

0 голосов
/ 19 декабря 2018

Относительно вашего вопроса: MongoDB всегда возвращает полный объект, соответствующий вашему запросу, если только вы не добавите проекцию, указывающую, какие поля должны быть возвращены.Если вы действительно хотите вернуть только вложенный объект, вы можете использовать конвейер агрегации с оператором $ replaceRoot следующим образом:

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" },
 },
])

Это должно вернуть только нужные элементы.

Примечание: если вы все равно планируете удалять элементы из массивов, я бы посоветовал вам взглянуть на операцию $ pull, которая может удалить элемент из массива, если он соответствует определенному условию:

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

User.update(
  { 'wardrobe.items._id': "5c1a4b7d482bf501ed20ae4a"},
  { $pull: { 'wardrobe.items': {_id: "5c1a4b7d482bf501ed20ae4a"}},
  { multi: true }
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...