0

我们需要对具有数百万条记录(音乐元数据)的数据库进行全文搜索,而我只在 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 countryCodebut no。

我只是对如何规避这个问题以及为什么我没有找到某人发布的类似问题感到困惑。

如果我没有得到有意义的答案,我想我将不得不使用charGuidas <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似乎是正确的,但不确定为什么其他人没有被包括在内,但是如果用 对实体进行硬编码albumSalesAreaNamesfrom SalesArea where id = 1那么我会将albumSalesArea字段添加到结果中,所以它似乎from SalesArea where id = '${albumSalesAreaIds.salesAreaId}'"返回 null,这也由前面的“IN”测试确认。

4

2 回答 2

1

这看起来确实是一个简单地用多值字段解决的问题。如果您在此结构中使用多值字段,您将获得一个 ID=10 的文档,所有重复值将只存在一次,所有其他字段将是多值的。例如,NAME 字段将包含 4 个不同的国家,因此 country_code。

看看这篇文章如何构建你的 dataimportHandler 来实现这一点:

http://wiki.apache.org/solr/DataImportHandler#Full_Import_Example

基本上每个多值字段都需要一个查询:

<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>

于 2013-10-30T10:03:21.923 回答
0

(代表 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>
于 2016-12-07T08:17:05.680 回答