【问题标题】:Mongodb aggregation match ends with using field valueMongodb聚合匹配以使用字段值结束
【发布时间】:2019-06-22 18:53:43
【问题描述】:

注意:我使用的是 Mongodb 4,我必须使用聚合,因为这是更大聚合的一步

问题

如何在集合中查找包含以同一文档中另一个字段的值结尾的字段的文档?

让我们从这个集合开始:

db.regextest.insert([
{"first":"Pizza", "second" : "Pizza"},
{"first":"Pizza", "second" : "not pizza"},
{"first":"Pizza", "second" : "not pizza"}
])

以及精确匹配的示例查询:

db.regextest.aggregate([
{
    $match :  { $expr: { $eq: [ "$first" ,"$second" ] }   }    }
])

我会得到一份文件

{
    "_id" : ObjectId("5c49d44329ea754dc48b5ace"),
    "first" : "Pizza",    "second" : "Pizza"
}

这很好。

但是如何做同样的事情,但使用endsWith?

我在这里为start with 提出了另一个使用indexOfBytes 的问题。但是 indexOf 只返回第一个匹配,而不是最后一个

编辑:我找到了一个可以接受的答案(有很多自定义逻辑,我希望 Mongodb 团队会解决这个问题),这里是解决方案:

db.regextest.aggregate([
    {
        $addFields : {
            "tmpContains" : { $indexOfBytes: [ "$first", { $ifNull : [ "$second" , 0] }  ] }
        }
    },
    {
        $match: { "tmpContains" : { $gt : -1 } }
    },
    {
        $addFields : {
            "firstLen" : { $strLenBytes: "$first" }
        }
    },
    {
        $addFields : {
            "secondLen" : { $strLenBytes: "$second" }
        }
    },
    {
        $addFields : {
            "diffLen" : { $abs: { $subtract : [ "$firstLen", "$secondLen"] } }
        }
    },
    {
        $addFields : {
           "res" : { $substr:  [ "$first", "$diffLen", "$firstLen"] }
        }
    },
    {
        $match : { $expr : { $eq: [ "$res" , "$second" ] }}
    }
])

【问题讨论】:

  • 但是 indexOf 只返回第一个匹配项,而不是最后一个匹配项 如何?它将返回包含该搅拌的文档

标签: mongodb aggregation-framework


【解决方案1】:

您知道两个字段 ($strLenBytes) 的长度,您可以使用 $substr 获取 second 字段的最后一个 n 字符并将其与 first 字段进行比较,尝试:

db.regextest.aggregate([
    {
        $match: {
            $expr: {
                $eq: [ 
                    "$first", 
                    {
                        $let: {
                            vars: { firstLen: { $strLenBytes: "$first" }, secondLen: { $strLenBytes: "$second" } },
                            in: { $substr: [ "$second",  { $subtract: [ "$$secondLen", "$$firstLen" ] }, "$$firstLen" ] }
                        }
                    }
                ]
            }
        }
    }
])

以上聚合将为您提供相同的结果,因为字符串比较在 MongoDB 中区分大小写。要解决此问题,您可以在 $first$second 的计算子字符串上应用 $toLower 运算符,尝试:

db.regextest.aggregate([
    {
        $match: {
            $expr: {
                $eq: [ 
                    { $toLower: "$first" }, 
                    {
                        $let: {
                            vars: { firstLen: { $strLenBytes: "$first" }, secondLen: { $strLenBytes: "$second" } },
                            in: { $toLower: { $substr: [ "$second",  { $subtract: [ "$$secondLen", "$$firstLen" ] }, "$$firstLen" ] } }
                        }
                    }
                ]
            }
        }
    }
])

【讨论】:

    猜你喜欢
    • 2020-12-10
    • 1970-01-01
    • 1970-01-01
    • 2021-04-07
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 2019-07-17
    相关资源
    最近更新 更多