如何在MongoDB中读取匹配指定酒店名称的嵌套字段
MongoDB 获取匹配指定名称的单个酒店对象
问题背景
我在MongoDB中存储的文档结构如下:
[ { _id: new ObjectId("63608e3c3b74ed27b5bdf6fa"), latitude: 24.3065, hotels: [ { name: "Saunders Oconnor", latitude: 22.05869172633478, longitude: 88.661309245504, }, { name: "Saunders Oconnor", latitude: 22.05869172633478, longitude: 88.661309245504, }, ], }, { _id: new ObjectId("63608e3c3b74ed27b5bdf6fa"), latitude: 24.3065, hotels: [ { name: "Saunders Oconnor", latitude: 22.05869172633478, longitude: 88.661309245504, }, { name: "Saunders Oconnor", latitude: 22.05869172633478, longitude: 88.661309245504, }, ], } ];
我尝试用以下代码读取匹配指定酒店名称的字段:
const hotel = await places.find({ name: placeName }).project({ hotels: 1 }).toArray();
但返回的是包含整个hotels数组的文档:
[ { _id: new ObjectId("63608e3c3b74ed27b5bdf6f8"), hotels: [ [Object], [Object], [Object], [Object], [Object] ] } ]
我期望得到单个匹配的酒店对象,格式如下:
{ name: "Saunders Oconnor", latitude: 22.05869172633478, longitude: 88.661309245504, }
解决方案
方法1:使用聚合管道(推荐)
通过拆分数组、精准筛选、投影字段,直接得到目标格式的对象:
const hotelResult = await places.aggregate([ // 匹配包含目标酒店的文档 { $match: { "hotels.name": placeName } }, // 将hotels数组拆分为单个文档 { $unwind: "$hotels" }, // 筛选出名称完全匹配的酒店 { $match: { "hotels.name": placeName } }, // 投影需要的字段,去除冗余的_id和外层结构 { $project: { _id: 0, name: "$hotels.name", latitude: "$hotels.latitude", longitude: "$hotels.longitude" } }, // 仅返回第一个匹配结果(若需要所有匹配可删除此步骤) { $limit: 1 } ]).toArray(); // 提取最终的酒店对象 const targetHotel = hotelResult.length > 0 ? hotelResult[0] : null;
方法2:使用$elemMatch投影(快速获取单条匹配元素)
如果只需要每个父文档中第一个匹配的酒店元素,可直接用投影筛选:
const result = await places.find( { "hotels.name": placeName }, { _id: 0, hotels: { $elemMatch: { name: placeName } } } ).toArray(); // 提取单个酒店对象 const targetHotel = result.length > 0 ? result[0].hotels[0] : null;
关键注意点
- 原查询条件
{ name: placeName }错误,因为name字段嵌套在hotels数组内,正确条件应为{ "hotels.name": placeName }。 - 若需要返回所有匹配的酒店对象,删除聚合管道中的
$limit:1即可。
内容的提问来源于stack exchange,提问作者Osama Abdullah
相关产品推荐
相关产品推荐

