#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