3

我希望在大量城市名称上构建一个自动完成的文本框。搜索功能如下:我想要对多词短语进行“开始于”搜索。例如,如果用户输入了“chicago he”,则只需要返回“Chicago Heights”等位置。
我正在尝试为此使用Lucene。我在理解如何实现这一点时遇到问题。

我已经尝试过我认为应该可行的方法:

我已经用 KeywordAnalyzer 索引了位置(我已经尝试过 TOKENIZED 和 UN_TOKENIZED):

doc.Add(new Field("Name", data.ToLower(), Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO));

并通过以下方式搜索它们(我还尝试了各种其他查询/分析器/等):

var luceneQuery = new BooleanQuery();
var wildcardQuery = new WildcardQuery(new Term("Name", "chicago hei*"));
luceneQuery.Add(wildcardQuery, BooleanClause.Occur.MUST);

我没有得到任何结果。将不胜感激任何建议。

4

2 回答 2

3

为此,您需要使用设置为您的字段编制索引,该Field.Index.NOT_ANALYZED设置与您使用的 UN_TOKENIZED 相同,因此它应该可以工作。这是我快速制作的一个工作样本进行测试。我正在使用 Nuget 上的最新版本

IndexWriter iw = new IndexWriter(@"C:\temp\sotests", new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), true);

Document doc = new Document();
Field loc = new Field("location", "", Field.Store.YES, Field.Index.NOT_ANALYZED);
doc.Add(loc);

loc.SetValue("chicago heights");
iw.AddDocument(doc);

loc.SetValue("new-york");
iw.AddDocument(doc);

loc.SetValue("chicago low");
iw.AddDocument(doc);

loc.SetValue("montreal");
iw.AddDocument(doc);

loc.SetValue("paris");
iw.AddDocument(doc);

iw.Commit();


IndexSearcher ins = new IndexSearcher(iw.GetReader());

WildcardQuery query = new WildcardQuery(new Term("location", "chicago he*"));

var hits = ins.Search(query);

for (int i = 0; i < hits.Length(); i++)
    Console.WriteLine(hits.Doc(i).GetField("location").StringValue());

Console.WriteLine("---");

query = new WildcardQuery(new Term("location", "chic*"));
hits = ins.Search(query);

for (int i = 0; i < hits.Length(); i++)
    Console.WriteLine(hits.Doc(i).GetField("location").StringValue());

iw.Close();
Console.ReadLine();
于 2012-08-28T19:44:13.253 回答
0

保证“开始于”搜索的唯一方法是在索引字符串的开头放置一个分隔符,因此“钻石戒指”的索引类似于“lucenedelimiter diamond ring lucenedelimiter”。这可以防止出现“著名的钻石岭度假村”的搜索出现在搜索“钻石 ri*”中。

于 2012-08-28T22:34:21.163 回答