У меня есть база данных компаний и людей, которые я хочу запросить с помощью 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 - любые указатели будут оценены.