我需要一些帮助才能进行搜索。 假设我有一个非常简单的文档结构,只有1个字段,标有名称。 我需要检索长度大于或小于指定值的所有名称。我的意思是String.length()。 范围过滤器在概念上似乎很接近,但我找不到一个很好的例子来编写我的具体案例。 谢谢你的帮助。
答案 0 :(得分:2)
使用长度添加NumericField,然后使用RangeQuery。有关示例,请参阅NumericField javadoc。
答案 1 :(得分:0)
这是MultiTermQuery的典型示例。它不在盒子里,但易于实现。看看WildCardQuery
扩展MultiTermQuery
。这样做非常相似。只需使用不同的FilterredTermEnum,使用term.text的长度来过滤术语(而不是术语文本本身)。
魔术发生在这里(此代码位于我帖子底部的自定义术语枚举器中):
protected internal override bool TermCompare(Term term)
{
if (field == term.Field())
{
System.String searchText = term.Text();
if (searchText.Length >= text.Length())
{
return true;
}
}
endEnum = true;
return false;
}
上面的代码查看了字段的所有术语,并根据构造函数中传递的术语长度检查它们的长度。对于任何至少那么长的字段,它都会产生真的。
public class MinLengthQuery : MultiTermQuery
{
public MinLengthQuery(Term term) : base(term)
{
}
protected internal override FilteredTermEnum GetEnum(IndexReader reader)
{
return new MinLengthTermEnum(reader, GetTerm());
}
}
这门课完成所有工作:
public class MinLengthTermEnum : FilteredTermEnum
{
internal Term searchTerm;
internal System.String field = "";
internal System.String text = "";
internal System.String pre = "";
internal int preLen = 0;
internal bool endEnum = false;
public MinLengthTermEnum(IndexReader reader, Term term):base()
{
searchTerm = term;
field = searchTerm.Field();
text = searchTerm.Text();
SetEnum(reader.Terms(new Term(searchTerm.Field(), "")));
}
protected internal override bool TermCompare(Term term)
{
if (field == term.Field())
{
System.String searchText = term.Text();
if (searchText.Length >= text.Length())
{
return true;
}
}
endEnum = true;
return false;
}
public override float Difference()
{
return 1.0f;
}
public override bool EndEnum()
{
return endEnum;
}
public override void Close()
{
base.Close();
searchTerm = null;
field = null;
text = null;
}
}
(我是一个lucene.net的人,但翻译应该很容易......从你的版本的Lucene的WildCardQuery和TermEnum源代码开始并从中工作可能会更容易。)