没有塞子的 Lucene 索引搜索
Lucene Index Search without stoppers
我正在对 Lucene 索引进行一些查询,现在我正在寻找有关此查询的拉丁短语。问题是其中一些短语包含我认为被视为塞子的词。例如,如果我的搜索词是 "a contrario sensu",结果为零,但如果我只搜索 "contrario sensu",我就有超过 100 个巧合。
问题是没有这个限制器我如何进行搜索?
我的代码是这样的
public IEnumerable<TesisIndx> Search(string searchTerm)
{
List<TesisIndx> results = new List<TesisIndx>();
IndexSearcher searcher = new IndexSearcher(FSDirectory.GetDirectory(indexPath));
QueryParser parser = new QueryParser("Rubro", analyzer);
PhraseQuery q = new PhraseQuery();
String[] words = searchTerm.Split(' ');
foreach (string word in words)
{
q.Add(new Term("Rubro", word));
}
//Query query = parser.Parse(searchTerm);
Hits hitsFound = searcher.Search(q);
TesisIndx sampleDataFileRow = null;
for (int i = 0; i < hitsFound.Length(); i++)
{
sampleDataFileRow = new TesisIndx();
Document doc = hitsFound.Doc(i);
sampleDataFileRow.Ius = int.Parse(doc.Get("Ius"));
sampleDataFileRow.Rubro = doc.Get("Rubro");
sampleDataFileRow.Texto = doc.Get("Texto");
results.Add(sampleDataFileRow);
}
}
我使用 StandardAnalyzer 构建索引并执行搜索
这是一个停用词。但是,当涉及到短语查询时,这并不意味着根本不考虑它。如果您尝试在解析后打印查询,您应该会看到类似以下内容:
Rubro:"? contrario sensu"
那个问号代表位置增量,在本例中是删除的停用词。所以它正在寻找开头已删除停用词的空隙的短语。
您可以使用 QueryParser.setEnablePositionIncrements(false)
在查询解析器中禁用位置增量,但您应该知道,如果索引中仍然有位置增量,这可能会给您带来问题,并且 运行短语中间的停用词。
StandardAnalyzer 将排除一组 停用词,其中包括 "a"(完整列表请参见 https://github.com/apache/lucenenet/blob/3.0.3-2/src/core/Analysis/StopAnalyzer.cs 的末尾)
查询时的分析风格与索引时使用的风格兼容很重要。这就是为什么你的 PhraseQuery 只能在 没有 "a" 的情况下工作,因为索引步骤删除了它。
您可以使用接受 ISet<string> stopWords
并传入 new HashSet<string>()
的 StandardAnalyzer ctor,例如:
new StandardAnalyzer(Version.LUCENE_30, new HashSet<string>())
这意味着 所有 个词将包含在该字段的标记流中。
在索引和查询时使用这个分析器,你会得到更好的结果。
但是,您应该注意到 StandardAnalyzer 也会对这些词进行一些改动。它被设计为"a good tokenizer for most European-language documents"。请参阅 https://github.com/apache/lucenenet/blob/3.0.3-2/src/core/Analysis/Standard/StandardTokenizer.cs 开头的评论以获取更多信息并检查它是否与您的用例兼容。
可能值得您花时间针对要编制索引的文本类型研究不同的分析器。
我正在对 Lucene 索引进行一些查询,现在我正在寻找有关此查询的拉丁短语。问题是其中一些短语包含我认为被视为塞子的词。例如,如果我的搜索词是 "a contrario sensu",结果为零,但如果我只搜索 "contrario sensu",我就有超过 100 个巧合。
问题是没有这个限制器我如何进行搜索?
我的代码是这样的
public IEnumerable<TesisIndx> Search(string searchTerm)
{
List<TesisIndx> results = new List<TesisIndx>();
IndexSearcher searcher = new IndexSearcher(FSDirectory.GetDirectory(indexPath));
QueryParser parser = new QueryParser("Rubro", analyzer);
PhraseQuery q = new PhraseQuery();
String[] words = searchTerm.Split(' ');
foreach (string word in words)
{
q.Add(new Term("Rubro", word));
}
//Query query = parser.Parse(searchTerm);
Hits hitsFound = searcher.Search(q);
TesisIndx sampleDataFileRow = null;
for (int i = 0; i < hitsFound.Length(); i++)
{
sampleDataFileRow = new TesisIndx();
Document doc = hitsFound.Doc(i);
sampleDataFileRow.Ius = int.Parse(doc.Get("Ius"));
sampleDataFileRow.Rubro = doc.Get("Rubro");
sampleDataFileRow.Texto = doc.Get("Texto");
results.Add(sampleDataFileRow);
}
}
我使用 StandardAnalyzer 构建索引并执行搜索
这是一个停用词。但是,当涉及到短语查询时,这并不意味着根本不考虑它。如果您尝试在解析后打印查询,您应该会看到类似以下内容:
Rubro:"? contrario sensu"
那个问号代表位置增量,在本例中是删除的停用词。所以它正在寻找开头已删除停用词的空隙的短语。
您可以使用 QueryParser.setEnablePositionIncrements(false)
在查询解析器中禁用位置增量,但您应该知道,如果索引中仍然有位置增量,这可能会给您带来问题,并且 运行短语中间的停用词。
StandardAnalyzer 将排除一组 停用词,其中包括 "a"(完整列表请参见 https://github.com/apache/lucenenet/blob/3.0.3-2/src/core/Analysis/StopAnalyzer.cs 的末尾)
查询时的分析风格与索引时使用的风格兼容很重要。这就是为什么你的 PhraseQuery 只能在 没有 "a" 的情况下工作,因为索引步骤删除了它。
您可以使用接受 ISet<string> stopWords
并传入 new HashSet<string>()
的 StandardAnalyzer ctor,例如:
new StandardAnalyzer(Version.LUCENE_30, new HashSet<string>())
这意味着 所有 个词将包含在该字段的标记流中。
在索引和查询时使用这个分析器,你会得到更好的结果。
但是,您应该注意到 StandardAnalyzer 也会对这些词进行一些改动。它被设计为"a good tokenizer for most European-language documents"。请参阅 https://github.com/apache/lucenenet/blob/3.0.3-2/src/core/Analysis/Standard/StandardTokenizer.cs 开头的评论以获取更多信息并检查它是否与您的用例兼容。
可能值得您花时间针对要编制索引的文本类型研究不同的分析器。