#node.js #arrays #mongodb #objectid
Вопрос:
Restaurants — это коллекция, в которой есть объекты, подобные приведенным ниже:
{
_id: new ObjectId("61723c7378b6d3a5a02d908e"),
name: 'The Blue Hotel',
location: 'Noon city, New York',
phoneNumber: '122-536-7890',
website: 'http://www.bluehotel.com',
priceRange: '$
Я использую приведенный ниже код, чтобы найти этот объект на основе предоставленного идентификатора проверки
async get(reviewId) {
const restaurantsCollection = await restaurants();
reviewId = ObjectId(reviewId)
const r = await restaurantsCollection.findOne({reviews: {$elemMatch: {_id: reviewId}}})
return r
Это возвращает весь объект из коллекции ресторанов, что мне делать, если я хочу, чтобы отображался только отзыв, идентификатор которого указан в get(reviewID)
Вывод:
{
_id: new ObjectId("61736a0f65b9931b9e428790"),
title: 'dom',
reviewer: 'firuu',
rating: 4,
dateOfReview: '25/1/2002',
review: ' bruh'
}
Ответ №1:
С помощью проекции укажите поля, которые нужно возвращать
Следующее возвращает только обзор, идентификатор которого указан в get(reviewID)
async get(reviewId) {
const restaurantsCollection = await restaurants();
reviewId = ObjectId(reviewId)
const r = await restaurantsCollection.findOne(
{ reviews: { $elemMatch: { _id: reviewId } } },
{ "reviews.$": 1 }
)
return r
}
Вы также можете использовать find вместо fineOne
Комментарии:
1. Он возвращает все обзоры, я хочу отобразить только соответствующий обзор
2. Привет, я обновил код. Пожалуйста, проверьте @swombhai
3. Я все равно получаю весь объект, когда возвращаю r, не уверен, почему
4. метод findOne узла js, насколько я знаю, принимает проекцию в качестве опции, поэтому его следует заменить на
{"projection" : { "reviews.$": true }}
test it maybe5. Есть ли способ представить _id с помощью строки вместо new ObjectId? Можно ли добавить toString() в функцию findOne?
Ответ №2:
Запрос
- замените
ObjectId("61736a0f65b9931b9e428789")
наreviewId
- это вернет отзывы, соответствующие
_id
в массиве - если вы хотите получить только первый, в случае, если всегда есть максимум 1, вы можете заменить последний проект на
{"$project": {"_id": 0, "review": {"$arrayElemAt": ["$reviews", 0]}}}
* не уверен, что это то, что вам нужно
aggregate(
[{"$match": {"reviews._id": ObjectId("61736a0f65b9931b9e428789")}}
{"$set":
{"reviews":
{"$filter":
{"input": "$reviews",
"cond":
{"$eq": ["$this._id", ObjectId("61736a0f65b9931b9e428789")]}}}}},
{"$project": {"_id": 0, "reviews": 1}}])
Комментарии:
1. Должен ли я куда-либо помещать toArray()? Я заменил код, но не получил результат
2. да, aggreagte вернет курсор, используйте
result.toArray()
3. ответ @Pramisha больше похож на ваш код, я думаю, используйте другой ответ, это совокупное решение, здесь вы можете сделать это только с помощью find .
Ответ №3:
Возможно, это неправильный ответ на ваш вопрос, но вы можете попробовать что-то вроде этого.
const r = await restaurantsCollection.findOne({reviews: {$elemMatch: {_id: reviewId}}})?.reviews.find(review => review._id.equals(reviewId))
,
cuisines: [ 'Mexican', 'Italian' ],
overallRating: 0,
serviceOptions: { dineIn: true, takeOut: true, delivery: true },
reviews: [
{
_id: new ObjectId("61736a0f65b9931b9e428789"),
title: 'asd',
reviewer: 'khoh',
rating: 3,
dateOfReview: '5/12/2002',
review: 'hey'
},
_id: new ObjectId("61736a0f65b9931b9e428790"),
title: 'dom',
reviewer: 'firuu',
rating: 4,
dateOfReview: '25/1/2002',
review: ' bruh'
}
]
}
Я использую приведенный ниже код, чтобы найти этот объект на основе предоставленного идентификатора проверки
Это возвращает весь объект из коллекции ресторанов, что мне делать, если я хочу, чтобы отображался только отзыв, идентификатор которого указан в get(reviewID)
Вывод:
Ответ №1:
С помощью проекции укажите поля, которые нужно возвращать
Следующее возвращает только обзор, идентификатор которого указан в get(reviewID)
Вы также можете использовать find вместо fineOne
Комментарии:
1. Он возвращает все обзоры, я хочу отобразить только соответствующий обзор
2. Привет, я обновил код. Пожалуйста, проверьте @swombhai
3. Я все равно получаю весь объект, когда возвращаю r, не уверен, почему
4. метод findOne узла js, насколько я знаю, принимает проекцию в качестве опции, поэтому его следует заменить на
{"projection" : { "reviews.$": true }}
test it maybe5. Есть ли способ представить _id с помощью строки вместо new ObjectId? Можно ли добавить toString() в функцию findOne?
Ответ №2:
Запрос
- замените
ObjectId("61736a0f65b9931b9e428789")
наreviewId
- это вернет отзывы, соответствующие
_id
в массиве - если вы хотите получить только первый, в случае, если всегда есть максимум 1, вы можете заменить последний проект на
{"$project": {"_id": 0, "review": {"$arrayElemAt": ["$reviews", 0]}}}
* не уверен, что это то, что вам нужно
Комментарии:
1. Должен ли я куда-либо помещать toArray()? Я заменил код, но не получил результат
2. да, aggreagte вернет курсор, используйте
result.toArray()
3. ответ @Pramisha больше похож на ваш код, я думаю, используйте другой ответ, это совокупное решение, здесь вы можете сделать это только с помощью find .
Ответ №3:
Возможно, это неправильный ответ на ваш вопрос, но вы можете попробовать что-то вроде этого.