2015-11-10 4 views
0

Я новичок в Solr и у меня есть следующая проблема:Solr запрос: SQL-подобный JOIN, GROUP BY, SUM(), где SUM()

У меня есть эти документы:

категории: контракт:

{ 
    "contract_id_s": "contract-ENG-00001", 
    "title_s": "contract title", 
    "ref_easy_s": "REFAAA", 
    "commitment_id_s": "ENG-00001", 
}, 

категория: обязательство:

{ 
    "commitment_id_s": "ENG-00001", 
    "title_s": "commitment title", 
    "status_s": "Validated", 
    "date_changed_status_s": "2015-09-30", 
    "date_status_initiated_s": "2015-09-27", 
    "date_status_confirmed_s": "2015-09-28", 
    "date_status_validated_s": "2015-09-30", 
}, 

категория: приверженность И sub_category_s: commitment_project:

{ 
    "id": "ENG-00001_AAA", 
    "commitment_id_s": "ENG-00001", 
    "project_id_s": "AAA", 
    "project_name_s": "project name", 
    "project_amount_asked_s": "2000", 
    "project_amount_validated_s": "2100" 
}, 
{ 
    "id": "ENG-00001_AAA2", 
    "commitment_id_s": "ENG-00001", 
    "project_id_s": "AAA", 
    "project_name_s": "project name", 
    "project_amount_asked_s": "1000", 
    "project_amount_validated_s": "1200" 
}, 

Для каждого обязательства может существовать договор. Для каждого обязательства могут быть некоторые платежи.

Вот что я хочу сделать: - по умолчанию выберите только обязательство, которое имеет не менее: . один sub_category_s: objective_project с значением project_amount_validated_s. . один контракт. - если отфильтровано по суммам, выберите только этот список, обязательства с SUM проекта_amount_validated_s> amount_min И < amount_max.

Я не знаю, какова наилучшая практика с точки зрения производительности? - Запрос идентификаторов обязательств, запрашивающих детали для них? - Есть ли способ присоединиться к информации о контракте в этом запросе? - Или лучше всего запросить каждый документ по одному?

Проблема в том, что я не хочу запрашивать бесполезные данные (производительность, пропускная способность).

ответ

0

Хорошо, я нашел решение, используя! Join.

Например, в PHP:

[ 
    'q' => "{!join from=id to=service_id score=none}uri:\\$serviceUri* AND -deleted:true", 
    'fq' => "{!cache=false}category:monthly_volume AND type:\"$type\" AND timestamp:[$strDateStart TO $strDateEnd]", 
    'alt' => 'json', 
    'max-results' => 1000, 
    'sort' => 'timestamp ASC', 
    'statsFields' => 'stats.field=value&stats.facet=timestamp', 
] 

Или с запросом URL: {! Присоединиться к + с = ид + к = sector_id + балл = NONE}!

http://localhost:8983/solr/fluks-admin/select?q= {присоединиться + с = URI + to = service + score = none} uri:/test-en/service-en * + AND + -deleted: true & fq = {! cache = false} category: indicator + AND + timestamp: [201608 + TO + 201610] + AND + type :("- 3" + OR + 2 + OR + 3) + AND + -deleted: true & wt = json & indent = true & json.facet = {sum_timestamp: {terms: {limit: -1, field: timestamp, facet: {sum_type: {terms: {limit: -1, field: type, facet: {sum_vol_value: "sum (vol_value)"}}}}}}}

1

Есть некоторые инструменты доступны для вас в виде:

Однако я не уверен, что вы можете делать все, что вы надеетесь в одном запросе (используя эти части). И даже если вы можете, сшивая их вместе, даже не приближается простота SQL-запроса SELECT...JOIN...GROUP BY...HAVING, который вы надеетесь воспроизвести. (Если вы не хотите, чтобы попробовать Solr 6 developer snapshot с поддержкой параллельного SQL)


НО Если это ваш единственный вариант использования, И Solr не является вашим основным хранилищу, я настоятельно рекомендую моделирования вашего Solr для вашего прецедента.

E.g.Начните с простого, денормализовать, и включать только поля в вашем DataModel, необходимых для поиска:

  • только один тип записи: commitment
  • Поля
    • commitment_id_s
    • title_s
    • date_changed_status_s
    • date_status_initiated_s
    • date_status_confirmed_s
    • date_status_validated_s
    • total_payments_asked (числовая сумма project_amount_asked из БД)
    • total_payments_validated (числовая сумма project_amount_validated из БД)
    • project_names (многозначный список поиска проекта)
    • contract_names (многозначный список для поиска имен контракта)

Тогда ваш запрос просто необходим фильтр:

total_payments_validated:[ <amount_min> TO <amount_max> ]

, чтобы применить критерии по умолчанию.

После поиска определил идентификаторы действия обязательств, соответствующих запросу Solr, а затем вернуться и запрос к базе данных источника для любой дополнительной информации, необходимой для отображения (детали проекта, детали контракта, даты и т.д. ...)

+0

Спасибо большое, я посмотрю на него в четверг! – Quezako