Solr DIH с многозначными полями и фасетированием

Я использую Solr для индексации набора данных, хранящегося в СУБД, с помощью SQL DIH. Один на столе использует отношение n-to-n. Для простоты (мое приложение намного сложнее этого) вот пример приложения: у человека есть имя, и с ним связаны 0..n ролей (роль описывается строкой role_name).

Table Person:
- id: int
- Name: string

Table roles
- id: int
- role_name: string

Table association
- id_person: int
- id_role: int

Два человека могут быть описаны как:

id=1, name=John Doe, roles=[programmer, father, soccer player]
id=2, name= Eric Smith, roles=[]

Вот чего я хотел бы добиться с помощью solr.

  1. Импортируйте данные с помощью DIH (может быть, с помощью вложенного SQL-запроса?)
  2. Запросите и представьте данные со всей информацией о человеке + роли человека
  3. Иметь возможность запрашивать, используя заданную роль, например. подскажите все лица с ролью=программист?
  4. Настройте фасетирование, чтобы создать список всех ролей, каждая из которых имеет количество вхождений во всех наборах данных.

Я ожидаю, что это будет возможно с помощью solr (я использую версию 6.4, но я могу легко обновить ее до последней версии 6.5). Кто-нибудь может объяснить, как это сделать, или указать на правильную информацию/учебник?

Спасибо

УМГ


person ugomaria    schedule 10.04.2017    source источник
comment
Оба идентификатора строк одинаковы?   -  person Ashraful Islam    schedule 10.04.2017
comment
извините, это опечатка, сейчас исправлю!   -  person ugomaria    schedule 10.04.2017


Ответы (2)


Да, это возможно в Solr.

Я предполагаю, что у одного человека нет огромного количества ролей
Вы можете создать свою схему solr, как показано ниже:

<field name="id" type="string" multiValued="false" indexed="true" required="true" stored="true"/>
<field name="name" type="string" indexed="false" stored="true"/>
<field name="roles" type="strings" indexed="true" stored="true"/>
<field name="cfname" type="text_general" indexed="true" stored="false" multiValued="false"/>
<copyField source="name" dest="cfname"/>

Здесь roles — это многозначное поле.

Теперь вы можете запросить имя человека: q=cfname:John

http://solr_node:8983/solr/collection_name/select?q=cfname%3AJohn

И список всех ролей, каждая с количеством вхождений во всех наборах данных: q=*:*, facet=true, facet.field=roles и rows=0

http://solr_node:8983/solr/collection_name/select?q=*%3A*&rows=0&facet=true&facet.field=roles
person Ashraful Islam    schedule 10.04.2017

некоторые хитрые вещи, которые вы должны принять во внимание:

  1. вы определяете роли как многозначные

     <field name="roles" type="string" indexed="true" stored="true" multiValued="true"/>
    
  2. в настройке DIH для оптимальной производительности сделайте это так (это для mysql, измените по мере необходимости для вашей БД): левое соединение, чтобы вы запускали один запрос (намного быстрее, чем выполнение внутреннего запроса для каждого человека) и используйте sql GROUP BY и преобразователь для преобразования ролей в многозначное поле:

     <entity name="person" pk="id" transformer="RegexTransformer" query="
        SELECT p.id... GROUP_CONCAT(DISTINCT COALESCE(r.name,'') SEPARATOR '|') AS roles FROM person p LEFT JOIN association a ON p.id_person = a.id_role LEFT JOIN roles r ON a.id_role=r.id 
        WHERE ...
        GROUP BY p.id, ...
            ">
        <field column="roles" name="roles" splitBy="\|"/>
    </entity>
    

Это в основном для оптимальной производительности индексации. После того, как вы его проиндексировали, запросы, которые вы хотите запустить, будут довольно простыми.

Конфигурация выше написана от руки и не тестировалась, могут быть некоторые опечатки и т. д., но надеюсь, вы уловили суть.

person Persimmonium    schedule 10.04.2017