Lucene 如何添加 QueryParser 参数 InOrder=true?
Lucene how can i add in QueryParser parametr InOrder=true?
我有文件的文本:
war force
force war
我执行“拆分”并在 TextWord 中保存单词:
TextWord[0]: war
TextWord[1]: force
TextWord[2]: force
TextWord[3]: war
我只想查找“war force”,但我的搜索也找到了“force war”。
我希望搜索考虑 2 条规则:
- 保持词序。 (如果我查询的 str = "war force" 而我只找到索引 0 和 1。这个 "force war" 是错误的);
- Slop = 0(所以单词“war”和“force”之间没有单词,正确的是“war force”,但是这个“war SOMEWORD力”将是错误的)
我试试这个:
Query query = parser.parse(" \"war force\"~0x ");
Query query = parser.parse(" \"war force\"~0 ");
Query query = parser.parse("war AND force");
Query query = parser.parse("war force");
但是这样的请求并没有得到想要的结果,告诉我你是怎么做到的?
我的代码:
Analyzer customAnalyzer = CustomAnalyzer.builder()
.withTokenizer("standard")
.build();
QueryParser parser = new QueryParser("tags", customAnalyzer);
Query query = parser.parse("\"war force\" AND NOT \"force war\"");
IndexSearcher searcher = new IndexSearcher(reader);
TopDocs docs = searcher.search(query, 10);
System.out.println(" ");
FastVectorHighlighter highlighter = new FastVectorHighlighter();
FieldQuery fieldQuery = highlighter.getFieldQuery(query);
FieldTermStack stack = new FieldTermStack(reader, 0, "tags", fieldQuery);
TermInfo myTermInfo = stack.pop();
while(myTermInfo != null){
System.out.println("word[" + myTermInfo.getPosition() + "]: " + myTermInfo.getText());
myTermInfo = stack.pop();
}
我的输出:
word[0]: war
word[1]: force
word[4]: force
word[5]: war
我需要的结果:
word[0]: war
word[1]: force
我看到了文档。如果我们有这样的请求:“Word1 Word2”,并且这些单词之间没有运算符,那么默认情况下会放置 OR 运算符。这意味着请求“warforce”将等于请求“forcewar”,因此会发现:1)“warforce”; 2)“强制war”。而且我不知道如何确保结果只有这个:“war force”。
告诉我怎么样?我错过了什么吗?
如果我使用荧光笔,我会得到结果:
?<b>war</b> <b>force</b> bookcase bookcase1
force war
我的带有荧光笔的代码:
Analyzer customAnalyzer = CustomAnalyzer.builder()
.withTokenizer("standard")
.build();
//... Above, create documents with two fields, one with term vectors (tv) and one without (notv)
IndexSearcher searcher = new IndexSearcher(reader);
QueryParser parser = new QueryParser("tags", customAnalyzer);
Query query = parser.parse(" \"war force\"~0 ");
//Query query = parser.parse("*Case");
//Query query = new PrefixQuery(new Term("tags", "book")); //Поиск чтобы слово начиналось на строку "book" - "bookcase"
TopDocs hits = searcher.search(query, 10);
SimpleHTMLFormatter htmlFormatter = new SimpleHTMLFormatter("<b>", "</b>");
Highlighter highlighter = new Highlighter(htmlFormatter, new QueryScorer(query));
for (int i = 0; i < hits.scoreDocs.length; i++) {
int id = hits.scoreDocs[i].doc;
Document doc = searcher.doc(id);
String text = doc.get("tags");
TokenStream tokenStream = TokenSources.getAnyTokenStream(searcher.getIndexReader(), id, "tags", customAnalyzer);
TextFragment[] frag = highlighter.getBestTextFragments(tokenStream, text, true, 100);//highlighter.getBestFragments(tokenStream, text, 3, "...");
for (int j = 0; j < frag.length; j++) {
if ((frag[j] != null) && (frag[j].getScore() > 0)) {
System.out.println((frag[j].toString()));
}
}
System.out.println("finish test");
}
但是如果我使用荧光笔,我没有找到单词的位置。
要排除字词或短语,您可以使用 -
运算符(“禁止”运算符):
"war force" -"force war"
因此,在 Java 中,这将是:
Query query = parser.parse("\"war force\" -\"force war\"");
您也可以使用 AND NOT
:
"war force" AND NOT "force war"
您可以在经典查询解析器中查看更多详细信息syntax documentation。
更新
与您第一次提出问题相比,问题发生了很大变化!
现在有2个新问题:
您的查询似乎正在检索不应检索的文档。
您无法获取匹配项的位置。
问题 1
我无法重现这个问题。假设我的索引中有 2 个文档:
Doc 1: State WEAPONRY war force word1 And force war Book WEAPONRY
Doc 2: State WEAPONRY war force 123 War WORD1 Force And war Book WEAPONRY
当我使用以下查询时:
"war force" AND NOT "force war"
我找到了 Doc 2,但没有找到 Doc 1 - 这是正确的。
我不知道您为什么会看到 incorrect/unexpected 结果。我想这可能是因为您的索引包含意外数据或可能使用了意外的索引方法。问题中没有任何内容可以帮助解释这一点。
问题2
现在,您的问题包含两个使用荧光笔的示例:
- 快速矢量荧光笔
- 标准荧光笔
但是,您的两个代码片段都不会报告匹配标记的位置。为此,您可以使用此答案中显示的方法:
当我使用该方法并使用与上面所示相同的数据和查询时,我得到以下结果:
Found term: war
Position: 3
Found term: force
Position: 4
同样,这是正确的:匹配的术语是找到的文档中的第 3 个和第 4 个词。
我有文件的文本:
war force
force war
我执行“拆分”并在 TextWord 中保存单词:
TextWord[0]: war
TextWord[1]: force
TextWord[2]: force
TextWord[3]: war
我只想查找“war force”,但我的搜索也找到了“force war”。 我希望搜索考虑 2 条规则:
- 保持词序。 (如果我查询的 str = "war force" 而我只找到索引 0 和 1。这个 "force war" 是错误的);
- Slop = 0(所以单词“war”和“force”之间没有单词,正确的是“war force”,但是这个“war SOMEWORD力”将是错误的)
我试试这个:
Query query = parser.parse(" \"war force\"~0x ");
Query query = parser.parse(" \"war force\"~0 ");
Query query = parser.parse("war AND force");
Query query = parser.parse("war force");
但是这样的请求并没有得到想要的结果,告诉我你是怎么做到的?
我的代码:
Analyzer customAnalyzer = CustomAnalyzer.builder()
.withTokenizer("standard")
.build();
QueryParser parser = new QueryParser("tags", customAnalyzer);
Query query = parser.parse("\"war force\" AND NOT \"force war\"");
IndexSearcher searcher = new IndexSearcher(reader);
TopDocs docs = searcher.search(query, 10);
System.out.println(" ");
FastVectorHighlighter highlighter = new FastVectorHighlighter();
FieldQuery fieldQuery = highlighter.getFieldQuery(query);
FieldTermStack stack = new FieldTermStack(reader, 0, "tags", fieldQuery);
TermInfo myTermInfo = stack.pop();
while(myTermInfo != null){
System.out.println("word[" + myTermInfo.getPosition() + "]: " + myTermInfo.getText());
myTermInfo = stack.pop();
}
我的输出:
word[0]: war
word[1]: force
word[4]: force
word[5]: war
我需要的结果:
word[0]: war
word[1]: force
我看到了文档。如果我们有这样的请求:“Word1 Word2”,并且这些单词之间没有运算符,那么默认情况下会放置 OR 运算符。这意味着请求“warforce”将等于请求“forcewar”,因此会发现:1)“warforce”; 2)“强制war”。而且我不知道如何确保结果只有这个:“war force”。 告诉我怎么样?我错过了什么吗?
如果我使用荧光笔,我会得到结果:
?<b>war</b> <b>force</b> bookcase bookcase1
force war
我的带有荧光笔的代码:
Analyzer customAnalyzer = CustomAnalyzer.builder()
.withTokenizer("standard")
.build();
//... Above, create documents with two fields, one with term vectors (tv) and one without (notv)
IndexSearcher searcher = new IndexSearcher(reader);
QueryParser parser = new QueryParser("tags", customAnalyzer);
Query query = parser.parse(" \"war force\"~0 ");
//Query query = parser.parse("*Case");
//Query query = new PrefixQuery(new Term("tags", "book")); //Поиск чтобы слово начиналось на строку "book" - "bookcase"
TopDocs hits = searcher.search(query, 10);
SimpleHTMLFormatter htmlFormatter = new SimpleHTMLFormatter("<b>", "</b>");
Highlighter highlighter = new Highlighter(htmlFormatter, new QueryScorer(query));
for (int i = 0; i < hits.scoreDocs.length; i++) {
int id = hits.scoreDocs[i].doc;
Document doc = searcher.doc(id);
String text = doc.get("tags");
TokenStream tokenStream = TokenSources.getAnyTokenStream(searcher.getIndexReader(), id, "tags", customAnalyzer);
TextFragment[] frag = highlighter.getBestTextFragments(tokenStream, text, true, 100);//highlighter.getBestFragments(tokenStream, text, 3, "...");
for (int j = 0; j < frag.length; j++) {
if ((frag[j] != null) && (frag[j].getScore() > 0)) {
System.out.println((frag[j].toString()));
}
}
System.out.println("finish test");
}
但是如果我使用荧光笔,我没有找到单词的位置。
要排除字词或短语,您可以使用 -
运算符(“禁止”运算符):
"war force" -"force war"
因此,在 Java 中,这将是:
Query query = parser.parse("\"war force\" -\"force war\"");
您也可以使用 AND NOT
:
"war force" AND NOT "force war"
您可以在经典查询解析器中查看更多详细信息syntax documentation。
更新
与您第一次提出问题相比,问题发生了很大变化!
现在有2个新问题:
您的查询似乎正在检索不应检索的文档。
您无法获取匹配项的位置。
问题 1
我无法重现这个问题。假设我的索引中有 2 个文档:
Doc 1: State WEAPONRY war force word1 And force war Book WEAPONRY
Doc 2: State WEAPONRY war force 123 War WORD1 Force And war Book WEAPONRY
当我使用以下查询时:
"war force" AND NOT "force war"
我找到了 Doc 2,但没有找到 Doc 1 - 这是正确的。
我不知道您为什么会看到 incorrect/unexpected 结果。我想这可能是因为您的索引包含意外数据或可能使用了意外的索引方法。问题中没有任何内容可以帮助解释这一点。
问题2
现在,您的问题包含两个使用荧光笔的示例:
- 快速矢量荧光笔
- 标准荧光笔
但是,您的两个代码片段都不会报告匹配标记的位置。为此,您可以使用此答案中显示的方法:
当我使用该方法并使用与上面所示相同的数据和查询时,我得到以下结果:
Found term: war
Position: 3
Found term: force
Position: 4
同样,这是正确的:匹配的术语是找到的文档中的第 3 个和第 4 个词。