【问题标题】:what is the effecient way to search a phrase in mongodb在mongodb中搜索短语的有效方法是什么
【发布时间】:2012-09-14 21:51:03
【问题描述】:

搜索包含不完全匹配的单词的短语的最佳方法是什么,例如:

description = "a cell phone that have an external memory"

我想搜索:

search = "a good phone"

是否有使用 mongodb 的提示,或者我是否使用 python 中的 Knuth-Morris-Pratt 字符串匹配(这会杀死服务器)?

【问题讨论】:

    标签: python mongodb search knuth-morris-pratt


    【解决方案1】:

    MongoDB 并不是真正适合这样的骗子。我建议您使用SphinxSearchSolr 等外部服务来满足您的搜索需求。

    【讨论】:

    • 谢谢你是数据库界的新手,我发现人们在谈论 Elasticsearch,因为它是唯一一个与 mongodb 有“联系”的人?还是我得到了过时的信息?
    • @AbdelouahabPp 我相信它也很好。我使用一种设计模式,将适当的数据库项分别添加到搜索存储中,并从松散耦合中获得了巨大的好处。因此,您可以将文档处理为专门用于搜索的表单(仅添加某些字段、处理其他字段等)。
    • @AbdelouahabPp 是的,我用 Sphinx 做这个。我在 Mongo 实例和 MySQL 实例之间复制数据,这很棒。 MySQL 处理繁重的 delta 索引等,让 mongo 安静地为用户提供美味的数据。
    • @AbdelouahabPp MongoDB 作为存储引擎非常棒,但这并不意味着它是一种搜索技术。搜索技术和存储引擎不应混淆。两者之间有明显的区别,你不应该把它们混为一谈。在 Sphinx 中 MySQL 仅用作数据提供者,它不是实际的搜索索引。那仍然是它自己的数据库。 Sincde delta 索引在任何数据库上都很繁重,最好将其从主要处理您的站点数据中分离出来,以便从任何数据库中获得最大的性能。
    • @AbdelouahabPp 分片通常由搜索技术或在我个人情况下由搜索技术和 MySQL 管理。 ElasticSearch 实际上内置了简单的分片,这实际上是一个命令。真的很好。
    【解决方案2】:

    您可以使用MapReduce 构建搜索索引,然后在结果集合中搜索。

    您的 map 函数会首先将描述拆分为单个单词。应该丢弃非常常见的单词,例如“a”或“the”。然后它会对每个单词进行一次发射。 Key 是单词,value 是当前处理文档的_id。

    然后您的 reduce 函数将用于收集包含每个单词的所有文档。它将返回所有数组合并为一个并删除重复项的键。

    然后,此 MapReduce 作业的结果集合将为描述中出现的每个单词包含一个文档。这些文档将包含单词和一个数组,其中包含它出现的文档的_id。添加索引后,您可以非常快速地搜索它。

    此 MapReduce 作业需要执行一次以构建搜索索引。当数据库中已经有大量数据时,这将需要一段时间。每当添加或删除文档或更改文档描述时,您都必须执行增量 MapReduce 以更新搜索索引。这个增量 MapReduce 将比初始的快得多,因此自动执行此操作应该是可行的。

    【讨论】:

    • 在 python 中直接作为 description.split() 的主要内容吗?
    【解决方案3】:

    这里没有人在搜索时实际引用过文档页面:http://www.mongodb.org/display/DOCS/Full+Text+Search+in+Mongo

    避免使用 Map Reduce 和 Regex 等无法扩展的方法的一个好方法是在文档中实际存储关键字数组。

    您将决定如何添加 etc 单词以及要删除哪些停用词,一旦完成,您只需将其塞入文档本身的一个大数组中。

    Map reduce 有时被认为是一种不好的方法,因为它不会出于性能和线程原因以及正则表达式,因为它在 90% 的情况下对索引的使用非常糟糕,除非前缀。我已经看到一个简单的正则表达式杀死了很多 mongodb 服务器,所以我知道它有多糟糕。

    我同意其他所有人的观点,但您确实应该研究外部 FTS 技术。我个人很喜欢 Sphinx:http://sphinxsearch.com/,因为它的速度、可扩展性和灵活性。不过我用过其他搜索技术,比如 Solr,它们都非常好。

    【讨论】:

    • 我最后做了什么,我已经将文本(最多 160 个字符转换为一个集合(列表(数组)),所以我将所有单词转换为标签,但仍然无法访问它们!它给我的错误!我将针对此错误发布新帖子
    【解决方案4】:

    对于 mongo db 字段的简单正则表达式搜索,您可以使用 find"$regex" 查询表达式。

    在 pymongo 中是db.your_collection.find({"description": {"$regex": "<insert regex here>"}})

    这将使您入门。正如其他人所说,MongoDB 不一定喜欢你这样打败它。您可能需要考虑更强大的解决方案来进行大量搜索。

    请考虑在您的数据库中进行正则表达式搜索的性能影响。

    在此处阅读 MongoDB 参考资料http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions

    【讨论】:

    • 是的,正则表达式会“杀死”服务器!特别是当我使用阻塞库时!所以mongodb的设计不会让全文搜索!只有黑客! :(
    • 是和不是。您应该限制正在搜索的记录。在该子集上执行搜索。您是在系统中搜索每部手机的description,还是可以按制造商或用户减少它。如果您必须在整个数据集上进行搜索,您将需要一个更强大的解决方案。 @Phillip 有一个有趣的观点,即以另一种方式减少集合。
    • 这只是用户的一个选项,因为我已经包括通过“usernam”搜索通过“geo coordonates”搜索,以及使用“exact location”搜索,所以用户会有很多结果并选择。
    【解决方案5】:

    只想为Elastic Search 添加一个插件。他们有大量的client libraries,包括几个用于 python 的。

    Solr 和 ElasticSearch 都是基于 Apache Lucene 构建的,但 ElasticSearch 与 Solr、IMO 相比具有一些优势,首先是它使用 JSON 而不是 XML。

    【讨论】:

    • 很抱歉这个问题,但我该怎么办?我是否使用 python 库从数据库中获取“描述”,并在 ES 中搜索“搜索”?
    【解决方案6】:

    mongo 3.0+:只需在带有短语的字段上使用文本索引。 https://docs.mongodb.org/v3.0/core/index-text/

    【讨论】:

      猜你喜欢
      • 2012-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-05
      • 1970-01-01
      相关资源
      最近更新 更多