Lucene的默认不允许领先的搜索词通配符, 但可以启用有:
QueryParser#setAllowLeadingWildcard(true)
据我所知,使用通配符领先的防止Lucene的使用索引。 拥有国内领先的通配符搜索必须扫描整个索引。
如何表现出领先的通配符查询的性能? 当它确定以使用setAllowLeadingWildcard(true)
?
我已经建立了与模板10万个文档的测试指标:
{ name: random_3_word_phrase }
该指数是360M的磁盘上。
我的测试查询表现良好,我一直无法真正表现出的性能问题。 例如,查询name:*ing
产生超过110万份文件,在不到1秒。 查询name:*ing*
产生在同一时间超过150万份文件。
这是怎么回事吗? 为什么不是这样慢? 为10,000,000文件还不够吗? 执行文件需要包含的不仅仅是一个单一的领域吗?
取决于你有多少内存,多少令牌指数是在内存中。
一个360MB的总指数可以很快搜索到任何旧的计算机上。 一个360GB指数将需要更长的时间...;)
举个例子,我启动了一个老2GB指数,并寻找“* E”。
在具有8GB的盒子,它返回500K打不到5秒。 我试着用的内存只有1GB的一箱相同的索引,并花了大约20秒。
为了进一步说明,这里的,基本上做了“** E *”类型的搜索1000万个的随机3个字的词组一些通用的C#代码。
static string substring = "E";
private static Random random = new Random((int)DateTime.Now.Ticks);//thanks to McAden
private static string RandomString(int size)
{
StringBuilder builder = new StringBuilder();
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
builder.Append(ch);
}
return builder.ToString();
}
static void FindSubStringInPhrases()
{
List<string> index = new List<string>();
for (int i = 0; i < 10000000; i++)
{
index.Add(RandomString(5) + " " + RandomString(5) + " " + RandomString(5));
}
var matches = index.FindAll(SubstringPredicate);
}
static bool SubstringPredicate(string item)
{
if (item.Contains(substring))
return true;
else
return false;
}
毕竟千万阶段已加载到列表中,它仍然只需要大约一秒钟的“VAR匹配= index.FindAll(SubstringPredicate);” 返回超过400万的点击量。
问题的关键是,记忆是快。 一旦事情不能再加载到内存中,你必须开始交换到磁盘时,你会看到性能命中。
如果我理解正确的话,该指数的一部分术语词典,这是所有索引项的排序列表。 当不带通配符或尾随通配符搜索,Lucene的可以利用的事实,许多方面有共同的前缀优势。 在另一方面,拥有国内领先的通配符搜索扫描整个学期字典。 这不是最优的,但是该术语词典趋于比索引的其他部分,诸如频率和位置数据是微小的,所以术语词典的一个全扫描通常不是大问题本身。