Полнотекстовый поиск Lucene работает только для меток, которые точно соответствуют строке поиска

У меня проблемы с тем, чтобы заставить полнотекстовый поиск работать с Apache Lucene. Я могу получить имена, когда введу всю этикетку, например "cat", но ввод "c" ничего не дает. Я использую RDF4J. Это SPARQL-запрос, который я использую:

SELECT DISTINCT ?e2 ?altLabel ?label ?description WHERE
    {
       {
          ?e2 search:matches ?match .
           ?match search:query ?string ;
                  search:property ?labelIri ;
                  search:snippet ?altLabel
        }
     ?e2 ?labelIri ?label.
     }

LuceneSailConnection затем преобразует его в:

Distinct
   Projection
      ProjectionElemList
         ProjectionElem "e2"
         ProjectionElem "label"
         ProjectionElem "description"
      Extension
         ExtensionElem (description)
            Var (name=description)
         Join
            Join
               Join
                  StatementPattern
                     Var (name=e2)
                     Var (name=_const_232d65d1_uri, value=http://www.openrdf.org/contrib/lucenesail#matches, anonymous)
                     Var (name=match)
                  StatementPattern
                     Var (name=match)
                     Var (name=_const_802884e6_uri, value=http://www.openrdf.org/contrib/lucenesail#query, anonymous)
                     Var (name=string)
               StatementPattern
                  Var (name=match)
                  Var (name=_const_f59a94f7_uri, value=http://www.openrdf.org/contrib/lucenesail#property, anonymous)
                  Var (name=labelIri)
            StatementPattern
               Var (name=e2)
               Var (name=labelIri)
               Var (name=label)

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

@Override
public void indexLocalKb(KnowledgeBase aKb) throws IOException
{
    Analyzer analyzer = new StandardAnalyzer();
    Directory directory = FSDirectory
        .open(new File(luceneIndexDir, aKb.getRepositoryId()).toPath());
    IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig(analyzer));

    try (RepositoryConnection conn = getConnection(aKb)) {
        RepositoryResult<Statement> stmts = RdfUtils
            .getStatementsSparql(conn, null, aKb.getLabelIri(), null,
                Integer.MAX_VALUE, false, null);
        while (stmts.hasNext()) {
            Statement stmt = stmts.next();
            String id = stmt.getSubject().stringValue();
            String label = stmt.getObject().stringValue();
            String predicate = stmt.getPredicate().stringValue();
            indexEntity(id, label, predicate, indexWriter);
        }
    }

    indexWriter.close();
}

private void indexEntity(String aId, String aLabel, String aPredictate,
    IndexWriter aIndexWriter)
{
    try {
        String FIELD_ID = "id";
        String FIELD_CONTENT = "label";
        Document doc = new Document();
        doc.add(new StringField(FIELD_ID, aId, Field.Store.YES));
        doc.add(new StringField(FIELD_CONTENT, aLabel, Field.Store.YES));
        aIndexWriter.addDocument(doc);
        aIndexWriter.commit();

        log.info("Entity indexed with id [{}] and label [{}], predicate [{}]",
            aId, aLabel, aPredictate);
    }
    catch (IOException e) {
        log.error("Could not index entity with id [{}] and label [{}]", aId, aLabel);
    }
}

Вы должны хотя бы упомянуть, какой API вы используете, учитывая, что Lucene соотв. Полнотекстовый поиск не является частью стандарта SPARQL. (Я бы предположил, что это Сезам или RDF4J)

UninformedUser 17.09.2018 21:42

Я бы сказал, что если вы хотите искать вещи, которые начинаются с c, то, согласно синтаксису запроса Lucene, запрос должен быть c*. Ср. docs.rdf4j.org/programming Раздел 5.1.2. Полнотекстовый поиск

rec 19.09.2018 21:17

@rec это звучит как правильный ответ для меня - действительно хотите опубликовать его как ответ?

Jeen Broekstra 20.09.2018 02:04

@rec Спасибо, это сработало.

Taro Jiang 20.09.2018 18:26
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
4
242
1

Ответы 1

Вы должны использовать синтаксис запросов Lucene. Ищите c* вместо c. См. http://www.lucenetutorial.com/lucene-query-syntax.html

Другие вопросы по теме