在有或没有 http(s) 或 www 的情况下匹配 Mongoose 中的任何 url

Match any url in Mongoose with or without http(s) or www

我想要实现的是找到一种方法来验证 URL 是否已经存在于 MongoDB 文档中,而无需保存 URL 两次,一次使用 HTTP (s)(www) 协议和其他清除 HTTP(s)(www) 以执行匹配。 例如,如果 MongoDB 文档包含一条记录:

'url': "http://mysite.co?search=pattern&co=43"

所以,我想执行搜索:

MyCollection.find({'url': "mysite.co?search=pattern&co=43"})...
MyCollection.find({'url': "http://mysite.co?search=pattern&co=43"})...
MyCollection.find({'url': "https://mysite.co?search=pattern&co=43"})...
MyCollection.find({'url': "http://www.mysite.co?search=pattern&co=43"})...
MyCollection.find({'url': "https://www.mysite.co?search=pattern&co=43"})...

搜索应该与文档中实际保存的 URL 匹配。

我正在尝试使用以下正则表达式:

MyCollection.find({'url': new RegExp('^https?:\/\/(www.)?(' + 'mysite.co?search=pattern&co=43' + ')+$', 'gim')})...

但是,我在创建正则表达式方面不是很聪明,而且我仍然在努力解决这个问题。似乎 URL 中的问号破坏了正则表达式,我不太确定是否只是使用 '?' 的替换至 '\?'才是正确的做法。

搜索必须与数据库中的 'exactly' 和 URL 匹配,但 HTTP(s)(www) 协议除外。我的意思是,如果文档中的 URL 包含其他参数:

'url': "http://mysite.co?search=pattern&co=43&other=more_params"

本次搜索应该不匹配

我正在使用 Mongoose 和 nodejs。

提前致谢。

更新:

根据您的回答,我对 URL:

的正则表达式和换码做了一些改进

首先,trim 和 'clean' HTTP(s) 或 (www) 的 URL 的函数:

String.prototype.url_clean = function() {
    return this.trim().replace(/^(http(s|):\/\/)?(www\.|)/g, '');
};

还有一个转义函数URL:

RegExp.escape = function(s) {
    return s.replace(/[-[\]{}()*+!<=:?.\/\^$|#\s,]/g, '\$&');
};

所以我可以执行搜索:

MyCollection.find({'url': new RegExp('^(http(s|):\/\/)?(www\.|)(' + RegExp.escape(url.url_clean()) + ')(|\s)+$', "gim")})

问题是您必须从正则表达式中转义 url 的特定元素(例如“?”)/^http(s|):\/\/(www\.|)mysite\.co\?search=pattern&co=43/

相反,我会编写一个脚本来提取所有记录,将它们分成单独的字段,保存新文档。查询这些新字段而不是使用正则表达式

看起来不错,你只是忘了转义一些字符:

db.getCollection('regex').find({
    "url": new RegExp('^https?:\/\/(www.)?(' + 'mysite\.co\?search=pattern&co=43' + ')+$', 'gim')
})

MongoDB 中有关正则表达式的更多信息,您可以阅读 here