使用正则表达式使用mongoose进行不区分大小写的查找

时间:2013-07-05 16:25:48

标签: javascript node.js mongodb mongoose

我正在使用带有mongoose的NodeJS,我的目标是检查用户请求的伪是否尚未使用。 我想让用户选择带有大写字母的伪,但如果“foo”已被使用,我不希望用户选择“Foo”。

我知道我可以使用.find({pseudo: /foo/i}),但我需要在正则表达式中注入一个变量:new RegExp(pseudoToCheck, 'i')

此时,我被卡住了,因为如果pseudoToCheck包含正则表达式使用的任何特殊字符,正则表达式将失败。

我应该使用函数来逃避'伪'吗? 有没有更简单的方法来做我想要的事情?

由于

(对不起我的英文)

2 个答案:

答案 0 :(得分:3)

我很确定没有一种更简单的方法可以做到你需要的东西而不首先使用如下函数逃避“神奇”的RegExp字符:

function escapeRegExpChars(text) {
    return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}

因此,假设您正在搜索用户句柄(伪)“$ Foo(。)Bar +”,您会:

var query = new RegExp(escapeRegExpChars(handle),'i')

产生:

/\$Foo\(\.\)Bar\+/i 

使用RegExp搜索数据库中的记录存在缺陷,最麻烦的是 RegExp必须单独应用于每个记录。这称为表的“完全扫描”,非常效率低。

为了显着提高性能(通过删除全表扫描的要求),我会在数据库中保留两个句柄副本,一个用于显示目的,另一个用于简化搜索。

要创建面向搜索的句柄,您可以:

function createEscapedHandle(handle){
    return handle.toLowerCase().replace(/(\W)/g,function(ch){
        return '%' + ch.charCodeAt(0).toString(16);
    });
}

var handle = '$Foo(.)Bar+',
             escapedHandle = createEscapedHandle(handle);

// where escaped handle is '%24foo%28%2e%29bar%2b'

将原始句柄及其转义版本保存在数据库中,然后搜索转义版本。

我相信你会发现,处理(将RegExp与每条记录相匹配)与保存转义版手柄所需的额外存储空间之间的权衡将为您提供显着更快的结果。

答案 1 :(得分:0)

使用符号进行不区分大小写的搜索。 MongoDB控制台:

db.keywordsdocs.find({keyword:{ $regex:new RegExp('^' + 'string with symbols and different cases'.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '$', 'i')}});

猫鼬:

keywordsdocs.find({keyword:{$regex: new RegExp('^' + "string with symbols and different cases".replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '$', 'i')}},function(err, key) { console.log(key)});