我是mongodb的新手。我正在尝试使用提供的搜索参数来查找2个集合。
2集合具有以下结构:
servicetypes
_id:ObjectId(5ede7d9552d21c000436ac52)
TypeId:"1"
ServiceTypeTitle:"Body and Frame"
__v:0
servicesubtypes
_id:ObjectId(5ede85003bdd1c0004f26e71)
TypeId:"1"
SubTypeId:"1"
ServiceSubTypeTitle:"Air dam repaired"
__v:0
我尝试使用正则表达式和管道,但没有实现我想要的。以下是我编写的代码。
route.get('/FilterServices/:text', async (req, res) => {
var text = req.params.text
var list = await ServiceType.aggregate([
{
$lookup: {
from: "servicesubtypes",
localField: "TypeId",
foreignField: "TypeId",
as: "ServiceSubTypes"
}
},
{ "$match": { "ServiceSubTypes.ServiceSubTypeTitle": {$regex: text, $options:"i"} } }
]);
console.log(list)
res.send(list)
});
这将以以下方式向我返回数据:
[
{
_id: 5ede7d9552d21c000436ac52,
TypeId: '1',
ServiceTypeTitle: 'Body and Frame',
__v: 0,
ServiceSubTypes: [
[Object], [Object], [Object], [Object], [Object], [Object],
[Object], [Object], [Object], [Object], [Object], [Object],
...100 more items
]
},
{
_id: 5ede7d9652d21c000436ac53,
TypeId: '2',
ServiceTypeTitle: 'Brakes',
__v: 0,
ServiceSubTypes: [
[Object], [Object], [Object], [Object], [Object], [Object],
[Object], [Object], [Object], [Object], [Object], [Object],
...100 more items
]
},
{I have 5 more items in ServiceType but are not added due to regex}
]
使用上面的代码,如果找到值,则会返回特定ServiceType的整个ServiceSubTypes数组。如果找不到,则不会在列表中添加ServiceType。
如果找到匹配项,那么我只想要ServiceSubTypes数组中的特定记录。即
如果搜索参数是遮阳板,则结果应类似于
[
{
_id: 5ede7d9652d21c000436ac5a,
TypeId: '9',
ServiceTypeTitle: 'Vehicle',
__v: 0,
ServiceSubTypes: [
{
"_id": "5ede85683bdd1c0004f274d8",
"TypeId": "9",
"SubTypeId": "75",
"ServiceSubTypeTitle": "Right sunvisor replaced",
"__v": 0
},
{
"_id": "2ede8683dsaddc0004f2we4d8",
"TypeId": "9",
"SubTypeId": "75",
"ServiceSubTypeTitle": "Right sunvisor replaced",
"__v": 0
},
]
]
答案 0 :(得分:1)
在MongoDB中,当您在数组上使用$match
时-如果数组中至少有一个对象满足匹配条件(不仅保留了匹配对象,还将保留所有对象),您将获得整个数组最终文档包含该数组。
{我在ServiceType中还有5个项目,但由于正则表达式未添加}
正如我之前所说,对于ServiceType
集合中的这5个文档,ServiceSubTypes
数组中没有满足$match
中条件的对象。
由于我们已经知道它将获取整个数组,那么我们如何在聚合中仅仅个匹配数组中的对象?可以使用聚合运算符$filter来完成。在$match
阶段之后,您可以在$addFields
数组上进行$filter
到ServiceSubTypes
的阶段,以仅保留数组中匹配的对象,即;以获得理想的结果。
但是以另一种方式:如果我们可以控制从ServiceSubTypes
集合中检索到servicesubtypes
数组中的数据,那么我们就不必执行这些附加步骤:
您可以使用specify-multiple-join-conditions-with-lookup代替原始的$lookup
:
修改后的查询:
[
{
$lookup: {
from: "servicesubtypes",
let: { typeId: "$TypeId" },
pipeline: [
{ $match: { $expr: { $eq: ["$TypeId", "$$typeId"] } } },
{ $match: { ServiceSubTypeTitle: { $regex: text, $options: "i" } } }
],
as: "ServiceSubTypes",
}
},
{ $match: { ServiceSubTypes: { $ne: [] } } }
]