ПРИСОЕДИНЯЕТСЯ в Lucene - PullRequest
6 голосов
/ 31 марта 2011

Есть ли способ реализовать JOINS в Lucene?

Ответы [ 8 ]

12 голосов
/ 14 января 2012

Вы также можете использовать новый BlockJoinQuery;Я описал это в блоге здесь:

http://blog.mikemccandless.com/2012/01/searching-relational-content-with.html

8 голосов
/ 01 апреля 2011

Вы можете сделать общее объединение вручную - выполнить два поиска, получить все результаты (вместо верхней N), отсортировать их по ключу объединения и пересечь два упорядоченных списка.Но это очень сильно сокрушит вашу кучу (, если списки даже вписываются в нее).

Возможны оптимизации, но в очень специфических условиях.
Т.е. - вы делаете самостоятельно-присоединиться и использовать только (произвольный доступ) Filters для фильтрации, нет Queries.Затем вы можете вручную итерировать термины в двух полях соединения (параллельно), пересекать списки docId для каждого термина, фильтровать их - и вот ваше соединение.

Существует подход, который обрабатывает популярный сценарий использования простых родительских элементов.дочерние отношения с относительно небольшим числом дочерних элементов в документе - https://issues.apache.org/jira/browse/LUCENE-2454
В отличие от метода уплощения, упомянутого @ntziolis, этот подход корректно обрабатывает такие случаи, как: иметь несколько резюме, каждое с несколькими дочерними элементами work_experience, и попытаться найти кого-токоторый работал в компании NNN в год YYY.Если просто сгладить, вы получите резюме для людей, которые работали на NNN в любой год и работали где-то год YYY.

Альтернативой для обработки простых случаев родитель-потомок, действительно, является выравнивание документа, но убедитесь, что значения для разных дочерних элементов разделены большим пробелом posIncrement, а затем используйте запрос SpanNear, чтобы предотвратить несколько ваших подзапросовсоответствие между детьми.Об этом было несколько лет назад в LinkedIn, но я не смог ее найти.

3 голосов
/ 21 ноября 2012

Используйте joinutil .Это позволяет соединять время запроса.

См .: http://lucene.apache.org/core/4_0_0/join/org/apache/lucene/search/join/JoinUtil.html

3 голосов
/ 31 марта 2011
2 голосов
/ 31 марта 2011

Lucene не поддерживает отношения между документами , но объединение - это не что иное, как определенная комбинация нескольких AND в скобках, но вам нужно будет сначала выровнять отношения .

Пример (SQL => Lucene):

SQL:

SELECT Order.* FROM Order
JOIN Customer ON Order.CustomerID = Customer.ID
WHERE Customer.Name = 'SomeName'
AND Order.Nr = 400

Lucene:
Убедитесь, что у вас есть все необходимые поля и их соответствующие значения в документе, например: Customer.Name => "Customer_Name" и
Order.Nr => "Order_Nr"

Тогда запрос будет:

( Customer_Name:"SomeName" AND Order_Nr:"400" )
1 голос
/ 27 сентября 2013

В Lucene есть несколько реализаций, которые делают возможными такие соединения среди нескольких различных индексов. Numere (http://numere.stela.org.br/) включить это и сделать возможным получение результатов в виде набора результатов СУБД.

0 голосов
/ 27 декабря 2016

Немного поздно, но вы можете использовать Package org.apache.lucene.search.join: https://lucene.apache.org/core/6_3_0/join/org/apache/lucene/search/join/package-summary.html

Из их документации:

Включение поддержки индексации времениво время поиска, где объединенные документы индексируются как один блок документов с помощью IndexWriter.addDocuments ().

   String fromField = "from"; // Name of the from field
   boolean multipleValuesPerDocument = false; // Set only yo true in the case when your fromField has multiple values per document in your index
   String toField = "to"; // Name of the to field
   ScoreMode scoreMode = ScoreMode.Max // Defines how the scores are translated into the other side of the join.
   Query fromQuery = new TermQuery(new Term("content", searchTerm)); // Query executed to collect from values to join to the to values

   Query joinQuery = JoinUtil.createJoinQuery(fromField, multipleValuesPerDocument, toField, fromQuery, fromSearcher, scoreMode);
   TopDocs topDocs = toSearcher.search(joinQuery, 10); // Note: toSearcher can be the same as the fromSearcher
   // Render topDocs...
0 голосов
/ 27 сентября 2013

Вот пример Numere предоставляет простой способ извлечения аналитических данных из индексов Lucene

select a.type, sum(a.value) as "sales", b.category, count(distinct b.product_id) as "total"
from a (index)
inner join b (index) on (a.seq_id = b.seq_id)
group by a.type, b.category
order by a.type asc, b.category asc


    Join join = RequestFactory.newJoin();

    // inner join a.seq_id = b.seq_id

    join.on("seq_id", Type.INTEGER).equal("seq_id", Type.INTEGER);

    // left
    {
        Request left = join.left();
        left.repository(UtilTest.getPath("indexes/md/master"));
        left.addColumn("type").textType().asc();
        left.addMeasure("value").alias("sales").intType().sum();
    }

    // right
    {
        Request right = join.right();
        right.repository(UtilTest.getPath("indexes/md/detail"));
        right.addColumn("category").textType().asc();
        right.addMeasure("product_id").intType().alias("total").count_distinct();
    }

    Processor processor = ProcessorFactory.newProcessor();
    try {
        ResultPacket result = processor.execute(join);
        System.out.println(result);
    } finally {
        processor.close();
    }

Результат:

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<DATAPACKET Version="2.0">
  <METADATA>
    <FIELDS>
      <FIELD attrname="type" fieldtype="string" WIDTH="20" />
      <FIELD attrname="category" fieldtype="string" WIDTH="20" />
      <FIELD attrname="sales" fieldtype="i8" />
      <FIELD attrname="total" fieldtype="i4" />
    </FIELDS>
    <PARAMS />
  </METADATA>
  <ROWDATA>
    <ROW type="Book" category="stand" sales="127003304" total="2" />
    <ROW type="Computer" category="eletronic" sales="44765715835" total="896" />
    <ROW type="Meat" category="food" sales="3193526428" total="110" />

... продолжить

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...