Lucene:按字段的值长度搜索/过滤

时间:2011-07-12 22:18:58

标签: java search lucene

我需要一些帮助才能进行搜索。 假设我有一个非常简单的文档结构,只有1个字段,标有名称。 我需要检索长度大于或小于指定值的所有名称。我的意思是String.length()。 范围过滤器在概念上似乎很接近,但我找不到一个很好的例子来编写我的具体案例。 谢谢你的帮助。

2 个答案:

答案 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源代码开始并从中工作可能会更容易。)