我们需要对具有数百万条记录(音乐元数据)的数据库进行全文搜索,而我只在 Solr 上工作了大约 2 周,我需要一些关于索引的帮助。我正在使用DataImportHandler
并有生成如下结果的 SQL 查询:
正如您在上面的附图中看到的那样,id
(整数数据类型)在 SQL 结果中重复也用于 inDIH
并且当我将 uniqueKey 设置为<uniqueKey>id</uniqueKey>
solr 时覆盖了仅留下一条记录/行的值,实际上我认为是最后一个处理过的是带有countryCode
“TL”的那个。
当我第一次遇到这个问题时,我知道为什么 solr 会覆盖该值,这是正常的,所以我想为 db 中的每条记录添加一个全局标识符,一个 guid - 没有正确考虑,我最终得到了相同的重复项看看charGuid
哪个是来自 MySQL 的 uuid() 是重复的。
但是当我使用charGuid
(String 数据类型) 作为 uniqueKey to 时<uniqueKey>charGuid</uniqueKey>
,我得到了所有记录的索引并且没有任何内容被覆盖,但当然重复是不可避免的。我在这里看到的问题是,当我必须进行增量更新时,solr 将无法确切知道要更新哪个文档,事实上,来自管理控制台的快速测试显示,最后或第一次记录它的发现唯一键已更新。- 这是不可接受的。
我偶然发现了一篇文章引用multiValued="true"
,我认为在我的 SQL 中创建代表 JOIN 列的字段可以解决问题,但事实并非如此。我希望 id:10 的记录将返回一个 List of countryCode
but no。
我只是对如何规避这个问题以及为什么我没有找到某人发布的类似问题感到困惑。
如果我没有得到有意义的答案,我想我将不得不使用charGuid
as <uniqueKey>
which allows duplicate 然后使用Solr Document Deduplication Detection来处理我的索引的更新,但我想相信,有更好的方法。
更新 这是我的 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"/>
当我将我的 solr 响应与 SQL 结果进行比较时,我看到 countryCode 但 solr 没有,只返回
"albumSalesAreaId": [
1,
3
],
不知道为什么国家等没有出现。
更新 2
数据配置.xml
<document name="content">
<entity name="albums" query="select * from Album">
<entity name="tracks" query="select t.id, t.title, t.removed, t.productState from Track t where t.albumId='${albums.id}'">
<field column="id" name="id" />
<field column="title" name="trackTitle" />
<field column="removed" name="trackRemovedDate" />
<field column="productState" name="trackProductState" />
</entity>
<entity name="albumSalesAreaIds" query="select salesAreaId from AlbumSalesArea where albumId = '${albums.id}'">
<field column="salesAreaId" name="albumSalesAreaId"/>
</entity>
<entity name="albumSalesAreaNames" query="select name from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'">
<field column="name" name="albumSalesArea"/>
</entity>
<entity name="salesAreaCountryIds" query="select countryId from SalesAreaCountry where salesAreaId ='${albumSalesAreaIds.salesAreaId}'">
<field column="countryId" name="countryId" />
</entity>
<entity name="salesAreaCountry" query="select name from Country where id ='${salesAreaCountryIds.countryId}'">
<field column="name" name="countryName" />
</entity>
<field column="title" name="albumTitle"/>
<field column="removed" name="albumRemovedDate"/>
<field column="productState" name="albumProductState" />
</entity>
</document>
架构.xml
<field name="catchall" type="text_general" stored="true" indexed="true" multiValued="true"/>
<field name="publisher" type="text_general" indexed="true" stored="true"/>
<field name="uuid" type="binary" indexed="false" stored="true"/>
<field name="trackRemovedDate" type="tdate" indexed="true" stored="true"/>
<field name="albumRemovedDate" type="tdate" indexed="true" stored="true"/>
<field name="trackProductState" type="int" indexed="true" stored="true"/>
<field name="albumProductState" type="int" indexed="true" stored="true"/>
<field name="countryCode" type="text_general" indexed="true" stored="true" multiValued="true"/>
<field name="albumTitle" type="text_general" indexed="true" stored="true"/>
<field name="trackTitle" type="text_general" indexed="true" stored="true" multiValued="true"/>
<field name="guid" type="text_general" indexed="true" stored="true"/>
<!--new multivalue fields -->
<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"/>
<field name="albumSalesArea" type="text_general" indexed="true" stored="true" multiValued="true"/>
id:5 的示例 solr 响应
{
"responseHeader": {
"status": 0,
"QTime": 1,
"params": {
"indent": "true",
"q": "id:5",
"_": "1383221233535",
"wt": "json"
}
},
"response": {
"numFound": 1,
"start": 0,
"docs": [
{
"id": "5",
"catchall": [
"5",
"Test Album 5",
"2011-10-21 00:00:00.0",
"[B@261ca3cb",
"Test Track 1",
"Ya man 2",
"2011-10-17 16:21:29.0",
"1",
"1450412569164513280"
],
"albumTitle": "Test Album 5",
"albumRemovedDate": "2011-10-21T00:00:00Z",
"uuid": "6oT/MMl+RDaPyKpGK1KN0w==",
"trackTitle": [
"Test Track 1",
"Ya man 2"
],
"trackRemovedDate": "2011-10-17T16:21:29Z",
"albumSalesAreaId": [
1
],
"_version_": 1450412569164513300
}
]
}
}
id:5 的 SQL 结果
trackTitle
并且albumSalesAreaId
似乎是正确的,但不确定为什么其他人没有被包括在内,但是如果用 对实体进行硬编码albumSalesAreaNames
,from SalesArea where id = 1
那么我会将albumSalesArea
字段添加到结果中,所以它似乎from SalesArea
where id = '${albumSalesAreaIds.salesAreaId}'"
返回 null,这也由前面的“IN”测试确认。