Нам нужен полнотекстовый поиск базы данных с миллионами записей (музыкальные метаданные), и я работаю над Solr всего около 2 недель, мне нужна помощь в индексировании. Я использую DataImportHandler
и имею SQL-запрос, который генерирует такой результат:
Как вы можете видеть на прикрепленном изображении выше, id
(тип данных Integer) повторяется в результате SQL, также используемом для в DIH
, и когда я устанавливаю uniqueKey в <uniqueKey>id</uniqueKey>
, solr перезаписывает значения, оставляя только одну запись/строку, на самом деле я думаю последний обработанный файл с countryCode
'TL'.
Когда у меня впервые возникла эта проблема, я знал, почему solr перезаписывал значение, это нормально, поэтому я подумал о добавлении глобального идентификатора к каждой записи в db, guid - не подумав должным образом, я получил те же дубликаты, что и вы. см. charGuid
, который является uuid() из MySQL, дублируется.
Но когда я использую charGuid
(тип данных String) в качестве uniqueKey для <uniqueKey>charGuid</uniqueKey>
, я индексирую все записи, и ничего не перезаписывается, но, конечно, дубликаты неизбежны. Проблема, которую я вижу здесь, заключается в том, что когда мне нужно выполнить добавочное обновление, solr не сможет точно знать, какой документ нужно обновить. На самом деле быстрый тест из консоли администратора показал, что последняя или первая запись его найти с этим уникальный ключ обновляется. - Это неприемлемо.
Я наткнулся на статью со ссылкой на multiValued="true"
, я думал, что создание полей, представляющих столбец JOIN в моем SQL, поможет, но это не так. Я надеялся, что запись с id:10 будет возвращена со списком countryCode
, но нет.
Я просто озадачен тем, как обойти эту проблему и почему я не нашел подобную проблему, опубликованную кем-то.
Если я не получу осмысленного ответа, думаю, мне придется использовать charGuid
как <uniqueKey>
, что позволяет дублировать, а затем использовать 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, я вижу код страны, но solr не имеет его, только возвращает
"albumSalesAreaId": [
1,
3
],
Не знаю, почему не отображается страна и т. д.
Обновление 2
data-config.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>
schema.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"/>
пример ответа solr для id:5
{
"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
}
]
}
}
Результат SQL для id:5
trackTitle
и albumSalesAreaId
кажутся правильными, но не уверен, почему другие не были включены, однако, если жестко закодировать albumSalesAreaNames
enty с from SalesArea where id = 1
, то я получаю поле albumSalesArea
, добавленное к результату, поэтому кажется, что from SalesArea
where id = '${albumSalesAreaIds.salesAreaId}'"
возвращает значение null, также подтверждается от 'IN ' тест ранее.