28

我想在 MongoDB 中正则表达式搜索一个整数值。这可能吗?

我正在构建一个 CRUD 类型接口,该接口允许 * 在各个字段中使用通配符。我试图保持 UI 对一些整数字段保持一致。

考虑:

> db.seDemo.insert({ "example" : 1234 });
> db.seDemo.find({ "example" : 1234 });
{ "_id" : ObjectId("4bfc2bfea2004adae015220a"), "example" : 1234 }
> db.seDemo.find({ "example" : /^123.*/ });
> 

如您所见,我插入了一个对象,并且能够通过值找到它。如果我尝试一个简单的正则表达式,我实际上找不到对象。

谢谢!

4

2 回答 2

45

如果您想对数字进行模式匹配,在 mongo 中执行此操作的方法是使用 $where 表达式并传入模式匹配。

> db.test.find({ $where: "/^123.*/.test(this.example)" })
{ "_id" : ObjectId("4bfc3187fec861325f34b132"), "example" : 1234 }
于 2010-05-25T20:42:32.170 回答
19

我不是使用$where查询运算符的忠实拥护者,因为它评估查询表达式的方式,它不使用索引,并且如果查询使用用户输入数据则存在安全风险。

从 MongoDB 4.2 开始,您可以使用$regexMatch|$regexFind|$regexFindAllMongoDB 4.1.9+ 中的可用功能和$expr来执行此操作。

let regex = /123/;
  • $regexMatch$regexFind

    db.col.find({
        "$expr": {
            "$regexMatch": {
               "input": {"$toString": "$name"}, 
               "regex": /123/ 
            }
        }
    })
    
  • $regexFinAll

    db.col.find({
        "$expr": {
            "$gt": [
                { 
                    "$size": { 
                        "$regexFindAll": { 
                            "input": {"$toString": "$name"}, 
                            "regex": "123" 
                        }
                    }
                }, 
                0
            ]
        }
    })
    

从 MongoDB 4.0 开始,您可以使用$toString操作符,它是操作符的包装器来对整数$convert进行字符串化。

db.seDemo.aggregate([ 
    { "$redact": { 
        "$cond": [ 
            { "$gt": [ 
                { "$indexOfCP": [ 
                    { "$toString": "$example" }, 
                    "123" 
                ] }, 
                -1 
            ] }, 
            "$$KEEP", 
            "$$PRUNE" 
        ] 
    }}
])

如果您想要检索包含特定子字符串的所有文档,从 3.4 版开始,您可以使用$redact允许进行$cond逻辑处理的运算符。$indexOfCP.

db.seDemo.aggregate([ 
    { "$redact": { 
        "$cond": [ 
            { "$gt": [ 
                { "$indexOfCP": [ 
                    { "$toLower": "$example" }, 
                    "123" 
                ] }, 
                -1 
            ] }, 
            "$$KEEP", 
            "$$PRUNE" 
        ] 
    }}
])

产生:

{ 
    "_id" : ObjectId("579c668c1c52188b56a235b7"), 
    "example" : 1234 
}

{ 
    "_id" : ObjectId("579c66971c52188b56a235b9"), 
    "example" : 12334 
}

在 MongoDB 3.4 之前,您需要$project在文档中添加另一个计算字段,即您的数字的字符串值。

the$toLower和他的兄弟$toUpper运算符分别将字符串转换为小写和大写,但它们有一个未知的特性,即它们可以用于将整数转换为字符串。

运算符使用$match运算符返回与您的模式匹配的所有文档$regex

db.seDemo.aggregate(
    [ 
        { "$project": { 
            "stringifyExample": { "$toLower": "$example" }, 
            "example": 1 
        }}, 
        { "$match": { "stringifyExample": /^123.*/ } }
    ]
)

产生:

{ 
    "_id" : ObjectId("579c668c1c52188b56a235b7"), 
    "example" : 1234,
    "stringifyExample" : "1234"
}

{ 
    "_id" : ObjectId("579c66971c52188b56a235b9"), 
    "example" : 12334,
    "stringifyExample" : "12334"
}

现在,如果您想要检索包含特定子字符串的所有文档,那么更简单和更好的方法是在即将发布的 MongoDB(截至撰写本文时)中使用$redact允许进行$cond逻辑处理的运算符。$indexOfCP.

db.seDemo.aggregate([ 
    { "$redact": { 
        "$cond": [ 
            { "$gt": [ 
                { "$indexOfCP": [ 
                    { "$toLower": "$example" }, 
                    "123" 
                ] }, 
                -1 
            ] }, 
            "$$KEEP", 
            "$$PRUNE" 
        ] 
    }}
])
于 2016-07-30T09:12:29.017 回答