我的用户要求我提供类似Google的"查询术语建议(自动完成)对拼写错误的术语和一般见解很有用。 Mongo文本索引仅搜索完整且拼写正确的术语。
我需要访问文本索引本身,即其"单词"。我确实阅读了this crude solution,并且正在寻找比双重索引和管理术语(单词)引用计数更不易碎的东西。
我想做的就是获得以特定文本开头的N个索引标记。不要告诉我使用正则表达式搜索,因为它会破坏更快的文本索引。 我不想使用Elastic Search,Lucene或其他外部索引器:维护噩梦。文本搜索属于数据库,并且有一些限制,Mongo擅长于此。
答案 0 :(得分:0)
既然你对regexp说不,并且说你更喜欢使用内置的Mongodb文本搜索,我会建议我有时会实现的方法。它可以进行部分单词搜索,多个单词搜索和“有限范围”拼写错误,单数/复数,现在/过去时,动词,名词搜索。但请注意,如果每个字段包含1000个单词,则效率不高(也可能无法返回正确的值)。
Mongodb文本搜索仅匹配完整单词,因此字符串应相应地进行格式化。关键点是创建一个备用文本字段 - 在其上应用文本索引 - 而不是当前字段用于查找文本匹配。
此外,您必须从客户端输入
创建一个匹配的单词数组我将概述我的所作所为。假设集合中的字符串是
“使用MongoDB实现自动完成功能”
您将从中创建以下文本字符串并将其存储为另一个字段(文本索引字段)
“im imp impl implement implementmenti implementin implementation au aut auto co comp compl comp complet complete fe fea feat featu featureur feature mo mon mong mongo mongod mongodb”
文档插入前的过程如下所述
清理字符串 - 转换为小写,删除特殊字符,如 - ,()等
删除无关紧要的词语,如是,是,使用,等等,等等。
将剩余的单词推送到数组(input_array)。
对于input_array中的每个单词,取下长度为2,4,5的子串并将其推送到output_array。这些将匹配自动完成并提供一些拼写错误的掩护。例如,“实施”将生成“im”,“imp”,“impl”
对于input_array中长度为n的每个单词,取长度为n-3,n-2,n-1,n的子串并将其推入output_array。好处是它将涵盖一些语法错误/差异。例如 - 用户类型“实现”,带有“实现”的文本将返回正匹配。例如“实施”将生成“实施”,“实施”,“实施”,“实施”
合并数组以创建多个单词的文本字符串并将其插入集合
现在用户搜索输入也必须格式化为数组。这里还遵循步骤1,2,3,4,5来创建search_input_array。
将第4步应用于客户端搜索字符串的好处是它可以为拼写错误提供“一些”保护。例如用户类型“impdement”,格式化的数组将是('im','imp','impd','impde','impdem','impdeme','impdement')。您可以看到两个有效匹配可用于实现。其余的单词是不正确的单词,将匹配很少的条目
现在将步骤5应用于客户端搜索术语的好处是提供一些保护,防止语法变化,如现在/过去时,单数/复数,名词/动词等。例如用户类型“实现”, “实现”,“实现”,“实现”格式化的搜索数组将始终包含术语“实现”,通过为集合中的条目提供有效匹配。
必须使用
等查询进行匹配query [“$ text”] = {$ search:formatted_search_input_array};
如果要显示建议令牌,则应在结果集上处理一下。您应该从前n个匹配中获得“原始文本”。然后清理并分开单词。使用术语search_array进行直接子串匹配,并将匹配作为标记返回。但是如果你的小句话少于10个单词,你可以像google一样返回完整的文本(如果用户输入多个单词查询会更好)
如果你的琴弦很短,你会得到更好的结果。 当然,应该修改生成文本字符串的标准以满足您的需要。您还应该考虑将格式化的替代文本存储在另一个集合中,如果它很大,则通过objectid引用将其链接。
答案 1 :(得分:0)
快速搜索响应时间的关键或多或少取决于遍历存储/文件/数据库的项目数,源上的频率写入操作,限制量和网络或硬件开销。让我们打破这些,制定一个在所有这些方面都有所改进的策略。