首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果搜索项没有空格,则lucene.net匹配

如果搜索项没有空格,则lucene.net匹配
EN

Stack Overflow用户
提问于 2016-11-19 05:25:02
回答 1查看 462关注 0票数 1

我使用lucene.net在c# asp.net应用程序中的文章中执行搜索,这是我的索引中的一个示例文档:

代码语言:javascript
复制
var doc = new Document();
var title = new Field("Title", "the album hardwired to self-destruct released", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS);
title.Boost = 5;
doc.Add(title);
var ns_title = new Field("NoSpace_Title", "thealbumhardwiredtoselfdesctructreleased", Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS);
ns_title.Boost = 5;
doc.Add(ns_title);
doc.Add(new Field("Body", "the body text of the post", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
doc.Add(new Field("Id", "1", Field.Store.YES, Field.Index.NOT_ANALYZED));
writer.AddDocument(doc);

问题

如果我搜索selfdestructself destruct,就会被击中。

如果我搜索selfdestruct,我就不会被击中。

搜索方法

代码语言:javascript
复制
var searchWords = s.Split(' ').ToList();
var directory = GetDirectory();
var reader = IndexReader.Open(directory, true);
var searcher = new IndexSearcher(reader);
var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
var parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, "Title,NoSpace_Title,Body".Split(','), analyzer);
var booleanQuery = new BooleanQuery();

// Title:selfdestruct*NoSpace_Title:selfdestruct*Body:selfdestruct*
s = string.Join(" ", searchWords.Select(x => x.Contains("*") ? x : x + "*"));
Query query = parser.Parse(QueryParser.Escape(s));
query.Boost = 5;
booleanQuery.Add(query, Occur.SHOULD);

// Title:*selfdestruct*,NoSpace_Title:*selfdestruct*,Body:*selfdestruct*
// (I suppose this should work and get hit but it doesn't)
s = "*" + string.Join("", searchWords) + "*";
Query query2 = parser.Parse(QueryParser.Escape(s));
query2.Boost = 3;
booleanQuery.Add(query2, Occur.SHOULD);

// Title:selfdestruct~0.85 (fuzzy search)
s = string.Join(" ", searchWords.Select(x => x.Contains("~") ? x : x + "~0.85"));
Query query3 = parser.Parse(QueryParser.Escape(s));
booleanQuery.Add(query3, Occur.SHOULD);

var collector = TopScoreDocCollector.Create(1000, true);
searcher.Search(booleanQuery, collector);
var hits = collector.TopDocs().ScoreDocs;
var docs = hits.Select(x => searcher.Doc(x.Doc)).ToList();
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-20 07:42:53

您可以通过在分析器中添加一个ShingleFilter来支持这一点。

ShingleFilter将相邻的令牌组合成单个令牌,以便于在没有空格的情况下搜索它们。默认情况下,它也会输出Unigram(也就是说,它还将维护单个令牌)。所以,当你索引“自毁”时,它会索引标记"self“、"destruct”和"selfdestruct“。

在不创建您自己的自定义分析器的情况下,一个简单的方法是使用ShingleAnalyzerWrapper

代码语言:javascript
复制
var analyzer = new ShingleAnalyzerWrapper(
        new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30),
        2);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40689532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档