さまざまなソースからデータを収集してすばやく検索できるようにするために、Lucene RAMDirectory を作成しました。さまざまなアナライザーとインデックス戦略を理解するために何時間も費やしましたが、場合によっては、クエリの結果が期待どおりにならないことがあります。
デモ クラスは次のとおりです。
class LuceneDemo {
static final String ANIMAL = "animal";
static final String PERSON = "person";
private StandardAnalyzer analyzer = new StandardAnalyzer();
private IndexSearcher searcher;
private IndexWriter writer;
LuceneDemo() {
Directory ramDirectory = new RAMDirectory();
IndexWriterConfig config = new IndexWriterConfig(analyzer);
try {
writer = new IndexWriter(ramDirectory, config);
addDocument(createDocument(PERSON, "DR-(frankenstein)"));
addDocument(createDocument(ANIMAL, "gray fox"));
addDocument(createDocument(ANIMAL, "island fox"));
writer.close();
IndexReader reader = DirectoryReader.open(ramDirectory);
searcher = new IndexSearcher(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
private Document createDocument(String type, String value) {
Document document = new Document();
document.add(new TextField("type", type, Field.Store.YES));
document.add(new TextField("name", value, Field.Store.YES));
document.add(new StringField("name", value, Field.Store.YES));
return document;
}
private void addDocument(Document document) {
try {
writer.addDocument(document);
} catch (IOException e) {
e.printStackTrace();
}
}
List<String> getDocuments(String type, String value) {
value = "*" + QueryParser.escape(value) + "*";
try {
QueryParser queryParser = new QueryParser("name", analyzer);
queryParser.setAllowLeadingWildcard(true);
queryParser.setDefaultOperator(QueryParser.Operator.AND);
BooleanQuery.Builder query = new BooleanQuery.Builder();
query.add(new TermQuery(new Term("type", type)), BooleanClause.Occur.MUST);
query.add(queryParser.parse(value), BooleanClause.Occur.MUST);
TopDocs docs = searcher.search(query.build(), 10);
return Arrays.stream(docs.scoreDocs).map(scoreDoc -> {
try {
return searcher.doc(scoreDoc.doc).get("name");
} catch (IOException e) {
return "";
}
}).collect(Collectors.toList());
} catch (ParseException | IOException e) {
e.printStackTrace();
}
return Collections.emptyList();
}
}
「ox」、「gray fox」、または「-(frankenstein)」を検索すると、コードはかなりうまく機能します。しかし、「DR-(フランケンシュタイン)」の検索結果はありません。私が何を間違えたのかわかりません。したがって、提案は大歓迎です。
// OK
luceneDemo.getDocuments(LuceneDemo.ANIMAL, "ox").forEach(System.out::println);
luceneDemo.getDocuments(LuceneDemo.ANIMAL, "gray fox").forEach(System.out::println);
luceneDemo.getDocuments(LuceneDemo.PERSON, "-(frankenstein)").forEach(System.out::println);
// NOT OK
luceneDemo.getDocuments(LuceneDemo.PERSON, "DR-(frankenstein)").forEach(System.out::println);
これがドキュメントのインデックス作成方法です -
基本的StringField
に、analyzer
トークン化せず、大文字と小文字を区別せずに- に関係なくフィールドにインデックスを付けます。一方、読者はStandardAnalyzer
すべての検索で大文字と小文字を区別して使用しています。したがって、「DR-(フランケンシュタイン)」を検索すると、一致しない「dr-(フランケンシュタイン)」が検索されます。
StandardAnalyzer を使用してコードを機能させるには、StringField に小文字のインデックスを付ける必要があります。
document.add(new StringField("name", value.toLowerCase(), Field.Store.YES));
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加