java - MongoDB + Solr表演

时间:2011-08-25 16:23:06

标签: java mongodb solr

我一直在四处寻找如何将MongoDB与Solr结合使用,这里的一些问题有部分反应,但没有什么真正具体的(更像是理论)。在我的应用程序中,我将在MongoDB中存储大量的文档(可能高达数亿),我想对这些文档的某些属性实现全文搜索,所以我猜Solr是最好的方法此

我想知道的是我应该如何配置/执行所有内容以使其具有良好的性能?现在,这就是我所做的(我知道它不是最佳的):

1-在MongoDB中插入对象时,我将其添加到Solr

SolrServer server = getServer();
SolrInputDocument document = new SolrInputDocument();
document.addField("id", documentId);
...
server.add(document);
server.commit();

2-当更新对象的属性时,由于Solr不能只更新一个字段,首先我从MongoDB中检索对象然后用对象和新属性的所有属性更新Solr索引并执行类似

的操作
StreamingUpdateSolrServer update = new StreamingUpdateSolrServer(url, 1, 0);
SolrInputDocument document = new SolrInputDocument();
document.addField("id", documentId);
...
update.add(document);
update.commit();

3-查询时,首先我查询Solr,然后在检索文档列表SolrDocumentList时,我会浏览每个文档并且:

  1. 获取文档的ID
  2. 从MongoDB获取具有相同id的对象,以便能够从那里检索属性
  3. 4-删除时,我还没有完成那部分而不确定如何在Java中完成它

    所以有人建议如何以更有效的方式为这里描述的每个场景做到这一点?喜欢这样做的过程,当在Solr中有大量文档并一次添加一个文档时,它不会花费1小时来重建索引?我的要求是用户可能希望一次添加一个文档,我希望他们能够在

    之后立即检索它。

2 个答案:

答案 0 :(得分:14)

你的方法实际上很好。一些流行的框架如Compass正在执行您在较低级别描述的内容,以便自动镜像到通过ORM框架执行的索引更改(请参阅http://www.compass-project.org/overview.html)。

除了你描述的内容之外,我还会定期重新索引MongoDB中的所有数据,以确保Solr和Mongo同步(可能没有你想象的那么长,具体取决于数量)文档,字段数,每个字段的令牌数量和分析器的性能:我经常使用复杂的分析器在不到15分钟的时间内创建5到8百万个文档(大约20个字段,但文本字段很短)的索引,只需确保您的RAM缓冲区不会太小,并且在添加所有文档之前不要提交/优化。

关于性能,提交成本高,优化成本非常高。根据对您最重要的事情,您可以在Solrconfig.xml中更改mergefactor的值(较高的值可提高写入性能,而较低的值可提高读取性能,10值是一个很好的值)。

您似乎害怕索引构建时间。但是,由于Lucene索引存储是基于段的,因此写吞吐量不应过多依赖于索引的大小(http://lucene.apache.org/java/2_3_2/fileformats.html)。但是,预热时间会增加,所以你应该确保

  • 有典型的(特别是对于加载字段缓存的排序)但在firstSearcher和solrconfig.xml配置文件中的newSearcher参数中没有太复杂的查询,
  • useColdSearcher设置为
    • false以获得良好的搜索效果,或
    • 如果您希望以较慢的搜索价格更快地考虑对索引执行的更改,则为true。

此外,如果数据在写入MongoDB后仅几个X毫秒就可以搜索,那么你可以使用UpdateHandler的commitWithin功能。这样Solr就不必经常提交。

有关Solr性能因素的更多信息,请参阅   http://wiki.apache.org/solr/SolrPerformanceFactors

要删除文档,您可以按文档ID(在schema.xml中定义)或查询删除:   http://lucene.apache.org/solr/api/org/apache/solr/client/solrj/SolrServer.html

答案 1 :(得分:1)

  1. 您还可以等待更多文档并仅在每X分钟为其编制索引。 (当然这在很大程度上取决于您的应用和要求)

  2. 如果您的文档很小并且您不需要所有数据(存储在MongoDB中),您只能通过存储它们而不是索引来放置Solr文档中所需的字段

  3. <field name="nameoyourfield" type="stringOrAnyTypeYouuse"索引 ="false"存储 ="true"/>