Каков наилучший способ интеграции Solr в качестве индекса с Oracle в качестве БД хранилища? - PullRequest
2 голосов
/ 01 октября 2010

У меня есть база данных Oracle со всеми «данными» и индекс Solr, где индексируются все эти данные. В идеале я хочу иметь возможность выполнять такие запросы:

select * from data_table где id in ([результаты запроса solr для 'строки поиска']);

Однако возникает одна ключевая проблема: Oracle не допустит более 1000 элементов в массиве элементов в предложении «in» (БОЛЬШОЕ ПРЕДЛОЖЕНИЕ, так как список объектов, которые я нахожу, очень часто> 1000 и обычно будет около 50-200 тыс. Элементов)

Я попытался обойти эту проблему, используя функцию «split», которая будет принимать строку значений, разделенных запятыми, и разбивать их на элементы массива, но затем я установлю ограничение в 4000 знаков для параметра функции с помощью SQL ( PL / SQL равен 32 тыс. Символов, но в некоторых случаях он все еще СЛИШКОМ ограничивает результаты в 80 000+)

Я также сталкиваюсь с проблемами производительности, используя WHERE IN (....), мне говорят, что это вызывает очень медленный запрос, даже когда указанное поле является индексированным полем?

Я пытался сделать рекурсивное "ИЛИ" для ограничения в 1000 элементов (иначе: идентификатор в (1 ... 1000 или (идентификатор в (1001 ... 2000)) или идентификатор в (2001 ... .3000))) - и это работает, но очень медленно.

Я думаю, что мне следует загрузить JAR-файлы Solr-клиента в Oracle и написать функцию Oracle на Java, которая будет вызывать solr и передавать результаты в виде списка, чтобы я мог сделать что-то вроде:

select * from data_table, где id in (select * from table (runSolrQuery ('my query text)))));

Это довольно сложно, и я не уверен, что это даже возможно.

Вещи, которые я не могу сделать:

  • Хранить полные данные в Solr (security + пределы хранения)
  • Пользователь Solr as Контроллер пагинации и заказа (вот почему я выбираю данные из БД)

Поэтому мне нужно выработать гибридный подход, в котором Solr действительно действует как поставщик полнотекстового поиска для Oracle. Помогите! Кто-нибудь сталкивался с этим?

Ответы [ 4 ]

2 голосов
/ 08 июня 2013

Проверьте это: http://demo.scotas.com/search-sqlconsole.php

Этот продукт, кажется, делает именно то, что вам нужно.

ура

1 голос
/ 01 октября 2010

Я не эксперт Solr, но я предполагаю, что вы можете получить результаты запроса Solr в коллекцию Java. Как только вы это сделаете, вы сможете использовать эту коллекцию с JDBC. Это позволяет избежать ограничения в 1000 литеральных элементов, поскольку ваш список IN будет результатом запроса, а не списком литеральных значений.

Доминик Брукс имеет пример с использованием коллекций объектов с JDBC . Вы бы сделали что-то вроде

Создать пару типов в Oracle

CREATE TYPE data_table_id_typ AS OBJECT (
  id NUMBER
);

CREATE TYPE data_table_id_arr AS TABLE OF data_table_id_typ;

В Java вы можете создать соответствующий массив STRUCT, заполнить этот массив из Solr, а затем связать его с оператором SQL

SELECT *
  FROM data_table
 WHERE id IN (SELECT * FROM TABLE( CAST (? AS data_table_id_arr)))
0 голосов
/ 14 января 2011

На ум приходят два решения.

Сначала рассмотрим использование специфичных для Oracle расширений Java для JDBC.Они позволяют вам передавать фактический массив / список в качестве аргумента.Вам может понадобиться создать сохраненный процесс (это было давно, так как я должен был это сделать), но если это сфокусированный вариант использования, он не должен быть слишком обременительным.

Во-вторых, если вывсе еще сталкиваются с границей, такой как пределы 1000 объектов, рассмотрите возможность использования параметра «строки» при запросе Solr и использовании его встроенной функции разбивки на страницы.

Я использовал этот метод массовой выборки с сохраненными процессами для получения большого количестваданные, которые нужно было положить в Solr.Вовлеките своего DBA.Если у вас есть хороший и вы используете специфические расширения Oracle, я думаю, вы должны достичь очень разумной производительности.

0 голосов
/ 04 октября 2010

Вместо использования длинного BooleanQuery, вы можете использовать TermsFilter (работает как RangeFilter, но элементы не обязательно должны быть в последовательности).

Вот так (сначала заполните свой TermsFilter терминами):

TermsFilter termsFilter = new TermsFilter();

        // Loop through terms and add them to filter
        Term term = new Term("<field-name>", "<query>");
        termsFilter.addTerm(term);

затем выполните поиск по индексу следующим образом:

DocList parentsList = null;
parentsList = searcher.getDocList(new MatchAllDocsQuery(),  searcher.convertFilter(termsFilter), null, 0, 1000);

Где искатель - это SolrIndexSearcher (см. Документацию java для получения дополнительной информации о методе getDocList): http://lucene.apache.org/solr/api/org/apache/solr/search/SolrIndexSearcher.html

...