查找mongo db中的正则表达式/管道

时间:2020-06-08 21:51:55

标签: node.js mongodb mongoose mongodb-query aggregation-framework

我是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
            },
    ]
]

1 个答案:

答案 0 :(得分:1)

在MongoDB中,当您在数组上使用$match时-如果数组中至少有一个对象满足匹配条件(不仅保留了匹配对象,还将保留所有对象),您将获得整个数组最终文档包含该数组。

{我在ServiceType中还有5个项目,但由于正则表达式未添加}

正如我之前所说,对于ServiceType集合中的这5个文档,ServiceSubTypes数组中没有满足$match中条件的对象。

由于我们已经知道它将获取整个数组,那么我们如何在聚合中仅个匹配数组中的对象?可以使用聚合运算符$filter来完成。在$match阶段之后,您可以在$addFields数组上进行$filterServiceSubTypes的阶段,以仅保留数组中匹配的对象,即;以获得理想的结果。

但是以另一种方式:如果我们可以控制从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: [] } } }
]