处理Solr中的大量ID

时间:2013-05-01 09:01:53

标签: solr solr4

我需要在Solr中执行在线搜索,即用户需要查找具有特定条件的在线用户列表。

我如何处理这个:我们将用户的ID存储在一个表中,并在Solr请求中发送所有在线用户ID,如

&fq=-id:(id1 id2 id3 ............id5000)

这种方法的问题在于,当ID变大时,Solr需要花费太多时间来解决,我们需要通过网络传输大量请求。

一个解决方案可以在Solr中使用join,但是在线数据会定期更改,我不能每次都对数据进行索引(例如5-10分钟,至少应该是一小时)。

其他解决方案我认为根据URL中的某些参数从Solr内部触发此查询。我对Solr的内部结构并不了解,所以不知道如何继续。

4 个答案:

答案 0 :(得分:3)

使用Solr4的软提交,提交已经变得足够便宜,可以直接在用户记录中实际存储“在线”标志,并且在您的查询中只有& fq = online:true。这减少了通过线路发送5000个id并解析它们所涉及的开销,并让Solr稍微优化了查询。每当有人登录或注销时,设置其状态并在更新时设置commitWithin。无论如何,它值得一试。

答案 1 :(得分:3)

我们通过实施数据分片来解决这个问题。

基本上,没有深入研究代码细节:

  • 编写自己的索引代码
    • 使用consistent hashing决定哪个ID转到哪个Solr服务器
    • 将每个用户数据索引到相关的分片(可以是多台机器)
    • 确保您有冗余
  • 查询Solr分片
    • 使用shards参数
    • 在Solr中进行分片查询
    • 启动EmbeddedSolr并使用它来执行分片查询
    • Solr将查询所有分片并合并结果,如果您需要限制每个分片的查询时间,它还会提供超时

即使完全按照我上面的说法,我也不相信Solr非常适合这一点。 Solr不太适合搜索不断变化的索引,而且如果您主要通过ID搜索而不需要搜索引擎。

对于我们的项目,我们基本上实现了所有索引构建,负载均衡和查询引擎,并且主要使用Solr作为存储。但是当分片为flaky并且性能不高时,我们已经开始使用Solr,我不确定它今天的状态是什么。

最后请注意,如果我今天从头开始构建此系统而没有我们过去4年所做的所有工作,我建议使用缓存来存储当前在线的所有用户(例如memcached或{ {3}})并且在请求时我会简单地迭代所有这些并根据标准过滤掉。按标准过滤可以独立缓存并逐步更新,如果匹配逻辑非常简单,迭代超过5000条记录也不一定非常耗时。

答案 2 :(得分:2)

任何强大的解决方案都包括将您的数据接近SOLR(批处理)并在内部使用它。在搜索期间没有运行非常大的请求,这是低延迟的事情。 你应该开发自己的过滤器;过滤器会偶尔缓存在线用户数据(例如,每分钟)。如果数据经常变化,请考虑实施PostFilter。

您可以在此处找到过滤器实施的一个很好的示例: http://searchhub.org/2012/02/22/custom-security-filtering-in-solr/

答案 3 :(得分:0)

  

一个解决方案可以在solr中使用join,但在线数据更改   经常和我不能每次索引数据(比如5-10分钟,它应该是   至少一小时)

我认为你可以很好地使用Solr加入,但经过一些即兴创作。

解决方案,我建议如下:

You can have 2 Indexes (Solr Cores)

 1. Primary Index (The one you have now) 
 2. Secondary Index with only two fields , "ID" and "IS_ONLINE"

您现在可以经常更新辅助索引(以秒为单位)并使其与您拥有的表保持同步,以便存储在线用户。

注意:即使经常更新,这个二级索引也不会降低任何性能,只要我们进行必要的调整,例如在delta-import等过程中使用适当的查询等。

您现在可以在这两个索引的ID字段上执行Solr join,以达到您想要的效果。以下是关于如何在Indexes / Solr Core之间执行Solr Joins的link