与我今天早些时候的问题有关。这也是关于这个主题的相关帖子。我们已经建立了一个实时搜索,可以从25万个名字中提取前20个响应,我们希望正确地提取数据。
目前,如果我使用:
db.collection.find({ "drug": { "$regex": "cols", "$options": "i" } })
然后我收到了来自MongoDB Atlas的电子邮件警告,上面写着Scanned Objects / Returned has gone above 1000
。这是因为我没有使用$search
,所以我没有使用文本索引。每个查询似乎都在扫描整个250K行,以获得最好的20个匹配。不幸的是,如果我使用这个:
db.collection.find({ $text: { $search: "dog cat" } })
虽然我确实没有被电子邮件轰炸,但搜索结果并不好,因为它们没有捕获部分字符串。。。例如,如果我搜索篮球运动员Zion Williamson
,当用regex键入部分字符串Zion Williams
时,我没有得到任何结果,它正确地返回Zion Williamson
。
坚持使用regex
方法并忽略这些电子邮件警告有问题吗?在mongo的$search
能够更好地捕获部分字符串之前,我不想在我的实时搜索中使用它。也许可以仅关闭此特定表的此特定警告的电子邮件警报?
提前感谢您对此有任何想法!
编辑:有问题的集合相当小(16MB(,大约有25万个文档,每个文档中有5个值。此外,$regex
和$search
的性能都足够(~0.1秒(——使用$regex
的全表扫描不会对数据获取性能造成太大损害。
正如您在编辑中添加的那样,问题主要归结为性能。但是,不仅要考虑单个查询的性能,还要考虑生产负载下的性能。您希望每秒执行多少个请求?
如果每秒钟做一次,甚至不经常做,那么现在对你来说就可以了。但是,如果数据集增长或您开始看到更多请求,该怎么办?那时候你就会开始遇到问题。
从你的例子来看,我不清楚一个不区分大小写的";starts_ with";搜索就是你所需要的。如果是这样的话,那么你实际上可以使用它的索引:
- 以to_lower或to_upper形式额外存储搜索字符串
- 将正则表达式更改为
^lower cased search string
现在您的搜索字符串不区分大小写,可以使用索引(相当于like 'string%'
(
但是,请记住,使用to_lower或to_upper可能会干扰您的文本(ToUpperInvariant((–MSDN的建议是错误的吗?(-当然,如果你仍然需要全文搜索,在这种情况下这是行不通的,你可以
- 遵守上述性能限制
- 使用普通全文搜索查询的功能限制
- 建立自定义的三角图索引(或进一步研究以改进postgres中的文本搜索(
- 寻找替代方案。如果你需要全文搜索,也许像ElasticSearch这样的特殊构建数据库更适合你的用例