最好的方法来过滤存储在solr / lucene中的远程数据库中的字段?

问题描述

| 我有一个代表电影实体的大约10万个文档的索引。 用户可以将电影放到各种列表中(例如收藏夹等) 这些列表存储在MysqL数据库中,未在solr中建立索引。 我可以将用户ID存储在代表一个列表的多值字段中,但这很糟糕,因为这些字段会变得非常非常长,并且索引也会出现问题。 所以目前我正在执行以下操作(伪代码):
$favorites = SELECT document_id FROM favorites WHERE user_id = $user_id
$documents = \'http://solr.com:8393/select/?q=XYZ&fq=document_id:(\'.join(\' OR \',$favorites);
这既好又快,但过滤器查询中的项目数限制为1024(我尝试过)。还可以过滤查询加起来。因此,如果我有一个查询的带有500个值的过滤器查询,那么我可以在另一个字段上拥有另一个524个过滤器的值。 现在还可以,因为我将每个列表的条目限制为1024,这虽然很多,但我认为这种方法非常笨拙,并且会产生大量开销。 有没有更好的解决方案?像编写直接连接到数据库之类的Solr模块一样?我想用PHP来做。 如果没有其他方法,我可以以某种方式提高1024的限制吗?因为它现在工作非常快!我认为,有了良好的硬件,这将不再是问题。 编辑:按照评论中的要求,我在这里发布了我的原始架构和一个有效的示例查询
<field name=\"film_id\" type=\"int\" indexed=\"true\" stored=\"true\" required=\"true\"/> 
<field name=\"imdb_id\" type=\"int\" indexed=\"true\" stored=\"true\" /> 
<field name=\"parent_id\" type=\"int\" indexed=\"true\" stored=\"true\"/> 
<field name=\"malus\" type=\"int\" indexed=\"true\" stored=\"true\"/> 
<field name=\"type\" type=\"int\" indexed=\"true\" stored=\"true\"/> 
<field name=\"year\" type=\"int\" indexed=\"true\" stored=\"true\" termVectors=\"true\"/> 
<field name=\"locale_title\" type=\"string\" indexed=\"false\" stored=\"true\"/> 
<field name=\"aka_title\" type=\"filmtitle\" indexed=\"true\" stored=\"true\" multiValued=\"true\" omitnorms=\"true\" termVectors=\"true\" /> 
<field name=\"sort_title\" type=\"string\" indexed=\"true\" stored=\"true\"/> 
<field name=\"director\" type=\"person\" indexed=\"true\" stored=\"true\" multiValued=\"true\" omitnorms=\"true\"/> 
<field name=\"director_phonetic\" type=\"person_phonetic\" multiValued=\"true\" omitnorms=\"true\"/> 
<field name=\"actor\" type=\"person\" indexed=\"true\" stored=\"true\" multiValued=\"true\" omitnorms=\"true\"/> 
<field name=\"actor_phonetic\" type=\"person_phonetic\" multiValued=\"true\" omitnorms=\"true\"/> 
<field name=\"country\" type=\"string\" indexed=\"true\" stored=\"true\" multiValued=\"true\"/> 
<field name=\"description\" type=\"text\" indexed=\"true\" stored=\"true\" /> 
<field name=\"genre\" type=\"genre\" indexed=\"true\" stored=\"true\" multiValued=\"true\" termVectors=\"true\"/> 
<field name=\"url\" type=\"string\" indexed=\"true\" stored=\"true\" multiValued=\"false\"/> 
<field name=\"image_url\" type=\"string\" indexed=\"false\" stored=\"true\" multiValued=\"false\"/>
<field name=\"rating\" type=\"int\" indexed=\"true\" stored=\"true\" required=\"false\" default=\"50\"/>
<field name=\"affiliate\" type=\"string\" indexed=\"true\" stored=\"true\" multiValued=\"true\"/>
<field name=\"product_type\" type=\"string\" indexed=\"true\" stored=\"true\" multiValued=\"true\"/>
<dynamicField name=\"product_*\" type=\"string\" indexed=\"true\" stored=\"true\" multiValued=\"true\"/>
<field name=\"blockbuster\" type=\"boolean\" indexed=\"true\" stored=\"true\" /> 
<copyField source=\"film_id\" dest=\"id\"/>
<field name=\"director_id\" type=\"string\" indexed=\"true\" stored=\"true\" multiValued=\"true\" termVectors=\"true\"/>
<field name=\"actor_id\" type=\"string\" indexed=\"true\" stored=\"true\" multiValued=\"true\" termVectors=\"true\"/>
这些是我对认schema.xml的补充 可以在此处查看示例搜索结果一个示例查询将是:
http://my-server.com:8983/solr/select/?
q=description:nazis
&fq=product_bluray:amazon
&fq=film_id:(1185616 1054606 88763 361748 78748)
用户将在此处搜索以下电影: 在亚马逊上可用 说明中带有“纳粹”一词的 并且在他最喜欢的清单上 该列表包括ID为1185616 1054606 88763 361748 78748的电影(文档),并存储在MysqL数据库中。 ps:我不知道我是否很好地提出了这个问题,希望它可以理解。如果没有,请随时进行编辑!     

解决方法

第一步是确保您确实要使用Solr。查看您的模式,那里有很多东西很容易受到带有基本文本索引的普通RDBMS的影响。花费半个小时的时间看一下postgresql,除非您已经确定常规的老式RDBMS带有一些额外的铃声,只是不会为您效劳。 Solr社区对此问题有很多兴趣,但是没有真正的解决方案。 显而易见的方法是,每当有人在多值字段中使用其用户名将“收藏的”文档收藏到文档中时,便对该索引进行重新索引。当然,这是脑筋急转弯,但这并不意味着它就行不通,这取决于您的用户有多少次与他/她的收藏夹列表打交道。如果您的文档很小(我假设它们只有几千个),并且您有足够的硬件将整个索引保留在内存中(可能因为您只有十万个文档),这可能是解决问题的方法考虑。您可以通过建立一个实际适合可用内存大小的索引并执行该策略来对其进行测试。看看它是否足够快。 如果人们一口气也没有添加大量的收藏夹,那么您也可以“分批”这些操作,例如: 第一天:我将十个项目添加到收藏夹中。您将其ID \粘贴在数据库中,然后使用该ID列表过滤我的查询。 晚上1:您更新了白天任何人喜欢的所有文档,并将我的用户名添加到“ favoritedBy \”多值字段中。从数据库中删除我喜欢的列表,因为该列表现在已显示在Solr索引本身中。 第2天:我将另外三个项目添加到我的收藏夹中。您同时过滤了收藏夹:myusername和id:(newID1或newID2或newID3)。 如果人们每天添加合理数量的收藏夹,而您晚上却没有太多流量,这可能对您有用。