关于mysql:MongoDB或Solr用于文档摄取,存储和分面搜索?

MongoDB or Solr for document ingestion, storage, and faceted search?

我需要在这里为我正在处理的项目做出架构决策。以下是要求:

  • 文件摄取(.doc,.pdf,.csv,也许是视频)

  • 实际的文件存储(我假设在服务器上的磁盘上
    一些引用来自DB的文件) - 以及数据库中可搜索和可分辨的某些字段?

  • 全文文档搜索

  • facetting(基于从文档中收集的字段的选择)
    每个文档的摄取可能不同 - 换句话说
    可能有200个方面但只有一些适用于每个文件)

  • 我使用rails作为服务器,目前是mySQL。我相信我在这里至少有两个明显的选择:

  • Solr的;从mySQL中的文档存储字段,并使用Sunspot gem作为Solr索引和facet定义。这里的好处似乎是快速搜索,分面,文档摄取实用程序。我不确定我的200(可能更多 - 真正动态定义)方面的问题。此外,考虑到文档有各种形状和大小,我想知道文档存储机制是否会更好。
  • MongoDB的;使用mongoid gem在MongoDB中存储文档内容。我对这里的文档摄取实用程序并不熟悉,虽然文档存储有明显的优势,但我相信mongodb在全文搜索方面做得很好,但是对于分面我需要使用多个查询进行聚合,这可能会很慢。
  • (我也知道我可以将Solr与MongoDB一起使用,但......不确定)。

    老实说,我对Solr和MongoDB都很新,可以在这里使用一些建议,因为我确信我缺少一些优点和缺点。


    听起来你可以使用elasticsearch。

    它是一个搜索引擎,使用与solr相同的底层lucene库,但您存储在其中的所有内容都是JSON文档。

    全文搜索,分面搜索和过滤许多不同的属性都很好。它确实内置了一些聚合(直方图刻面等),但您应该检查这些符合您的需求。

    根据您的弹性和吞吐量需求,构建跨多台计算机的elasticsearch集群也非常容易。

    它有几种红宝石绑定,包括轮胎,由Karel Mina?ík维护,他为弹性搜索工作。


    我对MongoDB和Solr都有很多经验(虽然没有任何关联)。

    根据您的需求,我推荐Solr。

    我已经处理了两个带有搜索问题的不同Web应用程序,第一个,我们从事务数据库中嵌入的Oracle Text切换到Solr。永不回头。

    尽管可能会让MongoDB做你想要的事情,但我怀疑你会花很多时间让MongoDB以你想要的方式运行,特别是在进行分面时。 Mongo的聚合框架相对较新。

    你说你需要为facet运行多个查询。我希望每个不同的值不是一个查询,就像所有类别一样,计算每个类别中的产品数量。在开发数据的第一天,这可能会正常工作,但要等到获得10,000个产品和500个类别以及50个用户同时搜索。然后,您有50个用户同时针对相同数据运行500个查询。你最终需要缓存它。

    Solr已经为你做了这一切。它的设计考虑了这些用例,并且无需运行N + 1查询就可以非常好地处理分面。 Solr还提供必要的缓存以避免频繁的磁盘I / O. Solr具有高度可配置性。您可以调整缓存大小,架构,分析器等,而无需重构代码。

    例如,我建议使用MongoDB进行搜索,当你的需求非常小并且不太可能发生重大变化时。例如,如果您想要前缀搜索,例如,提前输入,您只需将searchTokens字段添加到每个文档并自行进行分析。

    如果搜索用户集,每个用户可能看起来像:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    {
      userId: 'x',
      firstName: 'Brandon',
      lastName: 'Ramirez',
      searchTokens: [
        'b',
        'br',
        'bra',
        'bran',
        'brand',
        'brando',
        'brandon',
        'r',
        'ra',
        'ram',
        'rami',
        'ramir',
        'ramire',
        'ramirez'
      ]
    }

    我在MongoDB中使用了这种技术来避免Solr的复杂性。但这就是我所需要的。它是提前输入的,所以我不需要刻面,也不需要一组动态可过滤的字段,也不需要相关性评分。