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

前端之家收集整理的这篇文章主要介绍了php – 在solr / lucene中过滤存储在远程数据库中的字段的最佳方法?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个代表电影实体的大约100万个文档的索引.

用户可以将电影放在各种列表上(如收藏夹等)

这些列表存储在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"/>

theese是我对默认schema.xml的补充

可以查看样本搜索结果here.

示例查询将是:

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社区对此问题很感兴趣,但没有真正的解决方案.

显而易见的方法是每次有人在多值字段中使用用户名来收集“收藏”文档时重新索引.当然,这是脑死亡,但这并不意味着它不起作用,这取决于你的一个用户多么频繁地弄乱他/她的收藏列表.如果您的文档尺寸很小(我假设它们只有几K)并且您可以获得足够的硬件来将整个索引保留在内存中(可能因为您只有100K文档)这可能是考虑的方法.您可以通过构建一个可以实际适合可用内存的大小索引并实施策略来测试它.看看它是否足够快.

如果人们不能一次性添加大量收藏,您也可以“批量”执行这些操作,如下所示:

>第1天:我在我的收藏夹中添加了10个项目.您将其ID粘贴在数据库中并使用该ID列表来过滤我的查询.
>夜晚1:您更新了当天所有人都喜欢的所有文档,并将我的用户名添加到“favoritedBy”多值字段中.从数据库删除我最喜欢的列表,因为它现在在Solr索引本身中表示.
>第2天:我在我的收藏夹中添加了三个项目.您可以过滤favited:myusername和id

猜你在找的PHP相关文章