当前位置: 首页 > 面试题库 >

Lucene:多词短语作为搜索词

呼延庆
2023-03-14
问题内容

我正在尝试使用Apache Lucene创建可搜索的电话/本地业务目录。

我有街道名称,公司名称,电话号码等字段。我遇到的问题是,当我尝试按街道名称中包含多个单词(例如“新月”)的街道进行搜索时,没有返回结果。但是,如果我尝试仅用一个词(例如“新月”)进行搜索,那么我会得到所有想要的结果。

我正在使用以下索引数据:

String LocationOfDirectory = "C:\\dir\\index";

StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_34);
Directory Index = new SimpleFSDirectory(LocationOfDirectory);

IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE.34, analyzer);
IndexWriter w = new IndexWriter(index, config);


Document doc = new Document();
doc.add(new Field("Street", "the crescent", Field.Store.YES, Field.Index.Analyzed);

w.add(doc);
w.close();

我的搜索是这样的:

int numberOfHits = 200;
String LocationOfDirectory = "C:\\dir\\index";
TopScoreDocCollector collector = TopScoreDocCollector.create(numberOfHits, true);
Directory directory = new SimpleFSDirectory(new File(LocationOfDirectory));
IndexSearcher searcher = new IndexSearcher(IndexReader.open(directory);

WildcardQuery q = new WildcardQuery(new Term("Street", "the crescent");

searcher.search(q, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs;

我尝试过将通配符查询替换为短语查询,首先将整个字符串替换为字符串,然后在空白处将其拆分,然后将其包装在BooleanQuery中,如下所示:

String term = "the crescent";
BooleanQuery b = new BooleanQuery();
PhraseQuery p = new PhraseQuery();
String[] tokens = term.split(" ");
for(int i = 0 ; i < tokens.length ; ++i)
{
    p.add(new Term("Street", tokens[i]));
}
b.add(p, BooleanClause.Occur.MUST);

但是,这没有用。我尝试使用KeywordAnalyzer代替StandardAnalyzer,但是所有其他类型的搜索也停止了工作。我尝试用其他字符(+和@)替换空格,并在这种形式之间来回查询,但这仍然行不通。我认为这是行不通的,因为+和@是没有索引的特殊字符,但是我似乎找不到任何这样的字符的列表。

我开始发疯了,有人知道我做错了吗?


问题答案:

我发现尝试不使用QueryParser生成查询的尝试不起作用,因此我停止尝试创建自己的查询,而改用QueryParser。我在网上看到的所有建议都表明,应在建立索引期间在QueryParser中使用相同的分析器,因此我使用StandardAnalyzer来构建QueryParser。

这对本示例有效,因为在索引过程中StandardAnalyzer从街道“新月”中删除了“ the”一词,因此我们无法搜索它,因为它不在索引中。

但是,如果选择搜索“ Grove Road”,则开箱即用功能会出现问题,即查询将返回包含“ Grove”或“
Road”的所有结果。通过设置QueryParser可以很容易地解决此问题,使其默认操作为AND而不是OR。

最后,正确的解决方案是:

int numberOfHits = 200;
String LocationOfDirectory = "C:\\dir\\index";
TopScoreDocCollector collector = TopScoreDocCollector.create(numberOfHits, true);
Directory directory = new SimpleFSDirectory(new File(LocationOfDirectory));
IndexSearcher searcher = new IndexSearcher(IndexReader.open(directory);

StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);

//WildcardQuery q = new WildcardQuery(new Term("Street", "the crescent");
QueryParser qp = new QueryParser(Version.LUCENE_35, "Street", analyzer);
qp.setDefaultOperator(QueryParser.Operator.AND);

Query q = qp.parse("grove road");

searcher.search(q, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs;


 类似资料:
  • 问题内容: Lucene的手册已经清楚地解释了对包含两个单词的短语进行接近搜索的含义,例如 但是,我想知道搜索到底能做什么?是否允许相邻的单词最多相隔10个单词,或者所有的单词对都是这样? 谢谢! 问题答案: 斜率(接近度)的作用类似于编辑距离(请参阅参考资料)。因此,这些条款可以重新排序或添加额外的条款。这意味着接近度将是添加到整个查询中的最大术语数。那是: 将匹配: “雅加达lucene ap

  • 我正在努力在我们的应用程序中集成Lucene。Lucene目前正在工作,例如当我搜索“上传”时,文档中有一些叫做“上传”的文本,那么它就工作了,但是当我搜索“上传”时,那么它就不工作了。有什么想法吗? 代码: 谢谢你。

  • 我有一段说 我对代码的看法: 这是正确的做法吗??

  • 问题内容: 我想搜索包含许多单词的字符串,并检索与其中任何一个匹配的文档。我的索引方法如下: 这是我的搜索方法。我不想寻找特定的词组,但是其中的任何单词。用于搜索的分析器与用于索引的分析器相同。 我是Lucene的新手。有人可以帮我吗? 问题答案: 使用会精确地尝试将短语“单词列表”与短语坡度0匹配。 如果要匹配单词列表中的 任何 术语,可以使用: 或者,您也可以使用,以便您可以要求查询词的数量的

  • 我试图用一个词作为查询来查找匹配项,但它似乎找不到。我正在使用标准分析仪,但找不到准确的结果。 我的索引文档是: 如果使用通配符查询: 它会返回内容:“敏捷的棕色狐狸跳过懒惰的狗” 如果使用术语查询: 它会返回内容:“敏捷的棕色狐狸跳过懒惰的狗” 现在,我想用“狐狸”作为我的新名词 但是我不知道哪个是正确的查询,或者如何做。我已经尝试了QueryParser、TermQuery和MultiPhra