Solr使用重复的uniqueKey索引SQL记录
我们需要对一个有数百万条记录(音乐元数据)的数据库进行全文搜索,而我只在Solr上工作了大约2周,我需要一些索引方面的帮助。我使用的是Solr使用重复的uniqueKey索引SQL记录,solr,lucene,full-text-search,solr4,Solr,Lucene,Full Text Search,Solr4,我们需要对一个有数百万条记录(音乐元数据)的数据库进行全文搜索,而我只在Solr上工作了大约2周,我需要一些索引方面的帮助。我使用的是DataImportHandler,并使用SQL查询生成如下结果: <entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'"> <field co
DataImportHandler
,并使用SQL查询生成如下结果:
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
如上图所示,id
(整型数据类型)在SQL结果中重复,也用于DIH
,当我将uniqueKey设置为id
solr时,会将值覆盖,只留下一条记录/行,事实上,我认为最后处理的一条记录/行是带有countryCode
“TL”的记录
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
当我第一次遇到这个问题时,我知道solr为什么会覆盖这个值,这是正常的,所以我想在db中的每个记录中添加一个全局标识符,一个guid-没有正确思考问题,我最终得到了与您可以看到的相同的重复项charGuid
,它是MySQL中的uuid()
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
但是,当我使用charGuid
(字符串数据类型)作为charGuid
的唯一键时,我会将所有记录编入索引,不会覆盖任何内容,当然,重复是不可避免的。我在这里看到的问题是,当我必须进行增量更新时,solr将无法准确地知道要更新的文档,事实上,管理控制台的快速测试显示,最后或第一次使用该唯一密钥记录其查找结果已更新。-这是不能接受的
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
我偶然发现一篇文章引用了multiValued=“true”
,我认为在我的SQL中创建表示联接列的字段可以解决问题,但事实并非如此。我希望id为10的记录将返回一个countryCode
列表,但是没有
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
我只是对如何规避这个问题感到困惑,为什么我没有发现有人发布了类似的问题
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
如果我没有得到一个有意义的答案,我想我将不得不使用charGuid
作为
,它允许复制,然后用于处理索引的更新,但我想相信,有更好的方法
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
更新
以下是我对data-config.xml和schema.xml的定义:
<entity name="albums" query="select * from Album">
<entity name="track" query="select t.id as id, t.title as trackTitle, t.removed as trackRemovedDate, t.productState from Track t where t.albumId='${albums.id}'"/>
<entity name="albumSalesAreaId" query="select asa.salesAreaId as albumSalesAreaId from AlbumSalesArea asa where asa.albumId='${albums.id}'"/>
<entity name="albumSalesArea" query="select sa.name as albumSalesArea from SalesArea sa where sa.id='${albumSalesAreaId.salesAreaId}'"/>
<entity name="salesAreaCountry" query="select sac.countryId as 'salesAreaCountry' from SalesAreaCountry sac where sac.salesAreaId ='${salesArea.id}'"/>
<entity name="countryId" query="select c.id as 'countryId' from Country c where c.id = '${salesAreaCountry.countryId}'"/>
<entity name="countryName" query="select c.name as 'countryName' from Country c where c.id = '${salesAreaCountry.countryId}'"/>
</entity>
**Schema.xml**
<!--new multivalue fields -->
<field name="albumSalesArea" type="int" stored="true" indexed="true" multiValued="true"/>
<field name="albumSalesAreaId" type="int" indexed="true" stored="true" multiValued="true"/>
<field name="salesAreaCountry" type="int" stored="true" indexed="true" multiValued="true"/>
<field name="countryId" type="int" indexed="true" stored="true" multiValued="true"/>
<field name="countryName" type="text_general" indexed="true" stored="true" multiValued="true"/>
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
不知道为什么国家等没有出现
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
更新2
data-config.xml
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
id为5的SQL结果
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
trackTitle
和albumSalesAreaId
似乎是正确的,但不确定为什么没有包括其他人。但是,如果从SalesArea(id=1)硬编码albumSalesAreaNames
整个,那么我会将albumSalesArea
字段添加到结果中,因此,似乎SalesArea中的其中id='${albumSalesAreaIds.salesAreaId}'
返回null,这也由前面的'IN'测试确认。这看起来确实是一个简单地用多值字段解决的问题。
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
如果在此结构中使用多值字段,您将获得一个ID=10的文档,所有重复的值将只存在一次,而所有其他字段将是多值的。例如,名称字段将包含4个不同的国家,因此国家代码
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
请阅读本文,了解如何构造dataimportHandler以实现这一点:
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
基本上,每个多值字段都需要一个查询:
<dataConfig>
<dataSource driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:/temp/example/ex" user="sa" />
<document name="products">
<entity name="item" query="select * from item">
<field column="ID" name="id" />
<field column="code" name="code" />
<entity name="countryName" query="select name from countrytable where item_id='${item.ID}'">
<field name="name" column="description" />
</entity>
<entity name="countryCode" query="select countryCode from countrytable where item_id='${item.ID}'">
</entity>
</entity>
</document>
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
(代表OP发布)
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
解决方案
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
这是我在无意中发现上面提到的multivalue=true文章时所设想的,我会做更多的挖掘,肯定会回来报告结果,感谢你至少给了我一些提示。Cheers我不知道如何在SQL查询中使字段成为多值字段,我尝试过选择entity.id、entity2.*和entity3.*等等,我无法为这些选定字段/列指定macth fieldname的别名,因此我不确定如何在schema.xml中将这些字段映射为多值。我是否正确地说,选定字段不能是字段,例如entity2.id、enity2.name?因此我选择了entity2.*、entity3.*…检查更新的答案。我添加了一个示例。您必须进行许多查询我认为您在查询中使用了错误的字段名。您编写了“select asa.salesAreaId as albumSalesAreaId”,因此该字段现在称为“albumSalesAreaId”,但在下一个查询中使用了旧字段名:${albumSalesAreaId.salesAreaId}。将其更改为“${albumSalesAreaId.albumSalesAreaId}”“你能在回答中更新模式吗?我认为你不应该用在。您是否先尝试了带“=”的常规查询?