我想在索引中查找特殊字符。如何搜索特殊字符(+ !?)在Lucene的
我逃過查詢字符串的所有特殊字符,但是當我爲+上的Lucene索引進行查詢它創建查詢爲+()。
因此,它在搜索領域沒有。
如何解決這個問題?我的索引包含這些特殊字符。
我想在索引中查找特殊字符。如何搜索特殊字符(+ !?)在Lucene的
我逃過查詢字符串的所有特殊字符,但是當我爲+上的Lucene索引進行查詢它創建查詢爲+()。
因此,它在搜索領域沒有。
如何解決這個問題?我的索引包含這些特殊字符。
如果您使用的是StandardAnalyzer
,將放棄非alphanum字符。嘗試使用WhitespaceAnalyzer
將相同的值編入索引並查看是否保留了所需的字符。它可能還會保留你不想要的東西:那時候你可能會考慮編寫自己的分析器,這基本上意味着創建一個TokenStream堆棧來完成你需要的處理。
例如,SimpleAnalyzer
實現以下管道:
@Override
public TokenStream tokenStream(String fieldName, Reader reader) {
return new LowerCaseTokenizer(reader);
}
剛剛較低情況下,令牌。
的StandardAnalyzer
做得更多:
/** Constructs a {@link StandardTokenizer} filtered by a {@link
StandardFilter}, a {@link LowerCaseFilter} and a {@link StopFilter}. */
@Override
public TokenStream tokenStream(String fieldName, Reader reader) {
StandardTokenizer tokenStream = new StandardTokenizer(matchVersion, reader);
tokenStream.setMaxTokenLength(maxTokenLength);
TokenStream result = new StandardFilter(tokenStream);
result = new LowerCaseFilter(result);
result = new StopFilter(enableStopPositionIncrements, result, stopSet);
return result;
}
您可以org.apache.lucene.analysis
從這些和其他成分混合&匹配,或者你可以寫自己的專業TokenStream
情況下,由您的自定義Analyzer
裹成一個處理管道。其他
有一點要看看是你用什麼樣的CharTokenizer
。 CharTokenizer
是一個抽象類,它指定用於標記文本字符串的機器。它被一些更簡單的分析儀使用(但不是StandardAnalyzer
)。 Lucene有兩個子類:LetterTokenizer
和WhitespaceTokenizer
。您可以通過創建自己的方法來保留所需的字符,並通過實施boolean isTokenChar(char c)
方法來打破不需要的字符。
也許這不是實際的作者,而是可以搜索特殊字符,你需要:
例如,它是如何工作的對我來說:
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.custom.CustomAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.RAMDirectory;
import org.junit.Test;
import java.io.IOException;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
public class LuceneSpecialCharactersSearchTest {
/**
* Test that tries to search a string by some substring with each special character separately.
*/
@Test
public void testSpecialCharacterSearch() throws Exception {
// GIVEN
LuceneSpecialCharactersSearch service = new LuceneSpecialCharactersSearch();
String[] luceneSpecialCharacters = new String[]{"+", "-", "&&", "||", "!", "(", ")", "{", "}", "[", "]", "^", "\"", "~", "*", "?", ":", "\\"};
// WHEN
for (String specialCharacter : luceneSpecialCharacters) {
String actual = service.search("list's special-characters " + specialCharacter);
// THEN
assertThat(actual, equalTo(LuceneSpecialCharactersSearch.TEXT_WITH_SPECIAL_CHARACTERS));
}
}
private static class LuceneSpecialCharactersSearch {
private static final String TEXT_WITH_SPECIAL_CHARACTERS = "This is the list's of special-characters + - && || ! () { } [ ]^\" ~ ? : \\ *";
private final IndexWriter writer;
public LuceneSpecialCharactersSearch() throws Exception {
Document document = new Document();
document.add(new TextField("body", TEXT_WITH_SPECIAL_CHARACTERS, Field.Store.YES));
RAMDirectory directory = new RAMDirectory();
writer = new IndexWriter(directory, new IndexWriterConfig(buildAnalyzer()));
writer.addDocument(document);
writer.commit();
}
public String search(String queryString) throws Exception {
try (IndexReader reader = DirectoryReader.open(writer, false)) {
IndexSearcher searcher = new IndexSearcher(reader);
String escapedQueryString = QueryParser.escape(queryString).toLowerCase();
Analyzer analyzer = buildAnalyzer();
QueryParser bodyQueryParser = new QueryParser("body", analyzer);
bodyQueryParser.setDefaultOperator(QueryParser.Operator.AND);
Query bodyQuery = bodyQueryParser.parse(escapedQueryString);
BooleanQuery query = new BooleanQuery.Builder()
.add(new BooleanClause(bodyQuery, BooleanClause.Occur.SHOULD))
.build();
TopDocs searchResult = searcher.search(query, 1);
return searcher.doc(searchResult.scoreDocs[0].doc).getField("body").stringValue();
}
}
/**
* Builds analyzer that is used for indexing and searching.
*/
private static Analyzer buildAnalyzer() throws IOException {
return CustomAnalyzer.builder()
.withTokenizer("whitespace")
.addTokenFilter("lowercase")
.addTokenFilter("standard")
.build();
}
}
}
請舉例說明您正在搜索的內容以及創建的內容。 「查詢爲+」是什麼意思? – morja 2011-05-24 08:53:39
我正在尋找特殊字符,如+! ?等等,我得到了解決方案。實際上,我們正在使用一些自定義分析器,並且由於應用了過濾器,因此給出了blanck查詢(+())。但是當我使用KeywordAnalyzer它工作。 **任何輸入如何?** – user660024 2011-05-24 09:47:49
您是否使用相同的分析器進行索引和查詢?請在調用搜索之前添加描述確切查詢的代碼示例以及如何處理它。 – 2011-05-24 12:35:44