Lucene: поиск / фильтрация по длине значения поля - PullRequest
4 голосов
/ 13 июля 2011

Мне нужна помощь в поиске.Скажем, у меня действительно простая структура документа, всего 1 поле с названием name.Мне нужно получить все имена, длина которых больше или меньше указанного значения.Под длиной я подразумеваю String.length ().Фильтр диапазона кажется близким по своей концепции, но я не смог найти хороший пример для написания моего конкретного случая.Спасибо за помощь.

Ответы [ 2 ]

2 голосов
/ 19 июля 2011

Добавьте NumericField, используя длину, затем используйте RangeQuery.См. NumericField javadoc для примера.

0 голосов
/ 14 июля 2011

Это классический пример 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 и работать с ним).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...