【问题标题】:regex/pipeline in lookup mongo db查找 mongo db 中的正则表达式/管道
【发布时间】:2020-09-27 23:46:29
【问题描述】:

我是 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 数组中的特定记录。即

如果我的搜索参数是 sunvisor 那么结果应该是这样的

[
      {
      _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
            },
    ]
]

【问题讨论】:

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


    【解决方案1】:

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

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

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

    既然我们已经知道它会得到整个数组,那么我们如何在聚合中的数组中获得only匹配的对象?它可以通过使用聚合运算符$filter 来完成。在$match 阶段之后,您可以在ServiceSubTypes 数组上使用带有$filter$addFields 阶段,以仅保留数组中匹配的对象,即;得到想要的结果。

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

    【讨论】:

    • 感谢您帮助我。我想了解更多关于这段代码{ $match: { $expr: { $eq: ["$TypeId", "$$typeId"] } } },你能解释一下发生了什么。
    • @Aforandroid :我们在let 中为ServiceType 集合中的TypeId 字段创建了一个局部变量,在$match 中我们将局部变量$$typeId 与字段@987654341 进行比较@ 在servicesubtypes 集合中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    • 2010-09-26
    • 1970-01-01
    相关资源
    最近更新 更多