как я могу получить один документ в mongoose?(не использовать aggregate)

#node.js #mongodb #mongoose

#node.js #mongodb #mongoose

Вопрос:

Я хочу вернуть объект одного индекса массива, но когда я запрашиваю, он возвращает мне все документы.

Это моя схема (userTb)

 const userTbSchema = new Schema({
  _id: mongoose.Schema.Types.ObjectId,
  userId: String,
  folders: [
    {
      folderTitle: String,
    }
  ]
}
 

и это результат запроса моей схемы (userTb).

 {
    "_id": "5fc4c13f32ab3174acb08540",
    "userId": "go05111",
    "folders": [
        {
            "_id": "5fb7b0473fddab615456b166",
            "folderTitle": "first-go"
        },
        {
            "_id": "5fb7b0473fddab615456b16b",
            "folderTitle": "second-go"
        }
    ]
}
 

Я хочу получить единственный объект папки { «folderTitle»: «first-go» }, например…

 {
    "_id": "5fb7b0473fddab615456b166",
    "folderTitle": "first-go"
}
 

итак, я запрашиваю так

 router.get('/folder/:folderId', (req, res, next) => {
    UserTb.find({ folders : { "$elemMatch" : { _id : req.params.folderId} } })
    .exec()
    .then(docs => {
        res.status(200).json({
            docs
        }); 
    })
    .catch(err => {
        res.status(500).json({
            error: err
        });
    });
});
 

но в результате ничего не изменилось.

Я попробовал несколько разных способов, но это не сработало.

как я могу это исправить в mongoose (не использовать aggregate)?

не могли бы вы мне помочь?

Ответ №1:

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

 db.collection.find({
  "folders.folderTitle": "first-go"
},
{
  "_id": 0,
  "folders": {
    "$elemMatch": {
      "folderTitle": "first-go"
    }
  }
})
 

Пример здесь

Выводятся только папки, имя которых совпадает first-go .

Обратите внимание, что вы получаете все значения, потому что используете $elemMatch into query. Согласно документации find получает два параметра: запрос и проекцию.

Запрос предназначен для фильтрации элементов, которые вы хотите получить, поэтому, если вы делаете только что-то вроде:

 db.collection.find({
  "folders._id": "5fb7b0473fddab615456b166"
})
 

Он вернет весь объект, которому соответствует этот фильтр. Пример здесь.
Обратите внимание, что возвращается только тот объект, в котором существует один folder объект с данным _id . Но не возвращается объект в массив, возвращается весь объект.

Итак, вам нужно задать свой запрос и после этого использовать проекцию $eleMatch .

Вы можете использовать пустой объект {} или поиск для фильтрации и получить сначала документ, а затем конкретный объект массива.

Таким образом, запрос должен выполнять что-то вроде:

 db.collection.find(
{
  /* First find the documents whose match this filter.
     Here you will get the entire document, not only the 
     object into the array you want*/
},
{
 /* Second filter the documents and get the value you want.
    In this case folderTitle = first-go*/
})
 

И, это правда, результат не совсем то, что вы хотите, это folders поле только со значениями, чьи match $elemMatch критерии. Но, на мой взгляд, использование only find — лучший подход.

Комментарии:

1. Спасибо за вашу помощь! Я могу решить свою проблему с вашей помощью. Большое вам спасибо: D