2016-11-10 4 views
0

У меня есть база данных компаний и людей, которые я хочу запросить с помощью Lucene (через Hibernate Search). Функция поиска реализована как поиск в стиле автозаполнения, где веб-страница будет предлагать совпадения по типу пользователя.Запрос индекса lucene с одиночными символами, например, инициалы лиц

Некоторые из компаний и людей идентифицируются с использованием инициалов, например.

  • G & H ГРАДОСТРОИТЕЛЬСТВО
  • JG ван дер Мерва

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

Однако у меня возникли проблемы с настройкой индекса и запроса таким образом, чтобы такой термин, как G & H, соответствовал документу. Используя такой термин, как CIVIL, будет много матчей. Однако одиночные символы с пробелами между ними не соответствуют чему-либо.

Приведенный ниже тест не работает на последней строке. Я не уверен в комбинации анализаторов, токенизаторов, фильтров & запросов, которые я должен использовать.

@Test 
public void testSearching() throws Exception { 
    Analyzer analyzer = new ReusableAnalyzerBase() { 
     @Override 
     protected TokenStreamComponents createComponents(String fieldName, Reader reader) { 
      StandardTokenizer tokenizer = new StandardTokenizer(Version.LUCENE_36, reader); 
      LowerCaseFilter lowerCaseFilter = new LowerCaseFilter(Version.LUCENE_36, tokenizer); 
      NGramTokenFilter filter = new NGramTokenFilter(lowerCaseFilter, 3, 20); 
      return new TokenStreamComponents(tokenizer, filter); 
     } 
    }; 
    Directory ramDirectory = new RAMDirectory(); 

    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_36, analyzer); 
    IndexWriter w = new IndexWriter(ramDirectory, config); 

    Document doc = new Document(); 
    doc.add(new Field("id", "819", Field.Store.YES, Field.Index.NOT_ANALYZED)); 
    doc.add(new Field("particulars.registeredName", "G & H CIVIL ENGINEERING", Field.Store.NO, Field.Index.ANALYZED)); 

    w.addDocument(doc); 
    w.close(); 

    // search 
    int numberOfHits = 200; 
    TopScoreDocCollector collector = TopScoreDocCollector.create(numberOfHits, true); 
    IndexSearcher searcher = new IndexSearcher(IndexReader.open(ramDirectory)); 

    PhraseQuery q = new PhraseQuery(); 
    q.add(new Term("particulars.registeredName", "civil")); 
    searcher.search(q, collector); 
    ScoreDoc[] hits = collector.topDocs().scoreDocs; 
    assertThat(hits.length, greaterThan(0)); 

    PhraseQuery phraseQuery = new PhraseQuery(); 
    phraseQuery.add(new Term("particulars.registeredName", "g & h")); 
    searcher.search(q, collector); 
    hits = collector.topDocs().scoreDocs; 
    assertThat(hits.length, greaterThan(0)); // this fails - no matches 

Я новичок в Lucene - любые указатели будут оценены.

ответ

0

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

Однако, обратите внимание, что с Hibernate Search вы не должны касаться Lucene внутренностей много: Hibernate Search будет автоматически выводить Lucene документы из субъектов во время индексации, а также построить читатель и коллекционер индекса по мере необходимости при запросе. Я настоятельно рекомендую вам избегать использования Lucene напрямую, если вы все еще новичок в Lucene/Hibernate Search: Lucene - мощный, но не простой инструмент для использования.

Это означает использование аннотированных (или программно отображаемых) объектов вместо создания документа вручную. См. the documentation, в частности, section about entity mapping и section about analysis.

Кроме того, при запросе вы можете использовать the Hibernate Search DSL. Вероятно, это будет проще, чем строить необработанные запросы Lucene. И когда ваш запрос был построен, вы также можете запросить Hibernate Search retrieve the results.

 Смежные вопросы

  • Нет связанных вопросов^_^