Как отсортировать по полю, которое имеет альтернативное значение, если ноль в люцене? - PullRequest
1 голос
/ 19 марта 2010

Я хочу отсортировать результаты поиска в lucene (.net) по полю даты (date1), но если date1 не задано, я бы хотел использовать date2.

Традиционный метод сортировки - это сортировка по дате1, а затем сортировка значений, одинаковых по дате 2. Это будет означать, что всякий раз, когда я возвращаюсь к дате2, эти значения будут в верхней (или нижней) части набор результатов. Я хотел бы чередовать значения date2 со значениями date1.

Другими словами, я хочу отсортировать по (date1! = Null? Date1: date2).

Возможно ли это в люцене?

Полагаю, я мог бы сделать это на этапе создания индекса (просто поместите соответствующее значение даты в новое поле), но у меня недостаточно контроля над процессом индексации, чтобы сделать это, поэтому я хотел бы отсортировать решение.

Есть идеи?

Спасибо Matt

Ответы [ 2 ]

2 голосов
/ 15 апреля 2010

Оказывается, это очень легко. Вы должны реализовать ScoreDocComparator, как предложил Ювал. Однако вам нужно реализовать его только один раз (у меня есть документ с двумя датами, я не хочу сортировать по дате1, затем по дате2, а по дате1, если она указана, или по дате2, если нет. Подумайте о фактической дате и предварительная дата. Я хочу использовать фактическую дату, если она доступна, но если нет, то предварительная дата достаточно хороша.)

Вот мой код:

public class ActualOrProvisionalDateSortComparator : ScoreDocComparator
{
    private readonly StringIndex actualDates;
    private readonly StringIndex provisionalDates;

    public TxOrCreatedDateSortComparator(IndexReader reader, FieldCache fieldCache)
    {
        actualDates = fieldCache.GetStringIndex(reader, "actualDate");
        provisionalDates = fieldCache.GetStringIndex(reader, "provisionalDate");
    }

    public int Compare(ScoreDoc i, ScoreDoc j)
    {
        var date1 = GetValue(i.doc);
        var date2 = GetValue(j.doc);

        return date1.CompareTo(date2);
    }

    public IComparable SortValue(ScoreDoc i)
    {
        return GetValue(i.doc);
    }

    public int SortType()
    {
        return SortField.CUSTOM;
    }

    private string GetValue(int doc)
    {
        return actualDates.Lookup[actualDates.Order[doc]] ?? provisionalDates.Lookup[provisionalDates.Order[doc]];
    }
}

Мой ActualOrProvisionalDateSortComparatorSource передается в FieldCache_Fields.DEFAULT, и мы ушли!

1 голос
/ 26 марта 2010

У меня есть идея, которая может работать:

  • использовать Поиск (запрос, фильтр, сортировка)
  • Чтобы создать объект Sort, используйте конструктор Sort (SortField [])
  • Создать поле SortField для обоих полей даты. для каждого из них используйте ScoreDocComparator для обработки случая нулевых значений. В этом случае функция Compare () вернет ноль. Пожалуйста, прочитайте это сообщение в блоге об использовании пользовательской сортировки в Java Lucene. Я считаю, что это не сложно перевести на Lucene.net.
...