【发布时间】:2012-07-23 14:15:24
【问题描述】:
到目前为止,我发现 Lucene 非常棒,但我在复制 LIKE 等效搜索时遇到了一些问题。
在我正在开发的应用程序中,我需要“简化”(LIKE)搜索和高级(全文)搜索选项。数据是基于用户的(姓名、位置等),所以不是大量的文本。
在过去,我只是创建一个连接数据库字段名称的 SQL 查询,并用通配符包围这些术语。我可以在我的应用程序中这样做,绕过 lucene 进行简单的用户数据搜索 - 但使用 lucene 会很好。
我尝试过正则表达式搜索
var query = QueryParser.Escape(_query);
var search = new RegexQuery(new Term("name",string.Concat(".*", _query, ".*")));
但它们只适用于一列。
我的一个想法是标记每个字段以产生类似于全文搜索的内容,例如:
姓名:保罗
所以我创建了以下名称字段...
保罗 波城 帕 奥尔 ul 亲
这会破坏在 LIKE SQL 搜索上使用 lucene 的意义吗?它真的会产生我想要的结果吗?
解决此问题的最佳方法是什么?
编辑:
稍微修改一下本题的代码:
Elegant way to split string into 2 strings on word boundaries to minimize length difference
生成这个标记器:
private IEnumerable<string> Tokeniser(string _item)
{
string s = _item;
const int maxPrefixLength = 10;
const int maxSuffixLength = 10;
const int minStemLength = 1;
var tokens = new List<string>();
for (int prefixLength = 0; (prefixLength + minStemLength <= s.Length) && (prefixLength <= maxPrefixLength); prefixLength++)
for (int suffixLength = 0; (suffixLength + prefixLength + minStemLength <= s.Length) && (suffixLength <= maxSuffixLength); suffixLength++)
{
string prefix = s.Substring(0, prefixLength);
string suffix = s.Substring(s.Length - suffixLength);
string stem = s.Substring(prefixLength, s.Length - suffixLength - prefixLength);
if (prefix.Length > 1)
if (!tokens.Contains(prefix))
tokens.Add(prefix);
if (suffix.Length > 1)
if (!tokens.Contains(suffix))
tokens.Add(suffix);
if (stem.Length > 1)
if (!tokens.Contains(stem))
tokens.Add(stem);
}
return tokens;
}
搜索结果确实相当于 LIKE 搜索。我的“用户”表的大小永远只有 9000 个实体 - 所以至少对我来说,这可能符合我的需要。
这样做有什么缺点吗(除了更大的 lucene 索引?)
【问题讨论】:
-
你可以试试
SingleCharTokenAnalyzersvn.apache.org/repos/asf/incubator/lucene.net/branches/… -
我发现这个分析器在较长的字段上非常慢。
-
嗨 L.B.我会看看!我在上面发布的字符串解析器运行良好。我不会将它用于超过 5-6 个单词的字段,但对于名称字段,它很棒。我稍微修改了它以在空格处拆分标记并简单地存储整个名称,然后分析不存储,其他“名称”字段中的名称标记位等
标签: search lucene lucene.net