XQuery: самый быстрый способ проверить даты

В соответствии с тем, что у меня есть этот файл XML:

<entries>
  <entry date="2012-10-09T12:09:09">...</entry>
  <entry date="2012-10-09T14:19:23">...</entry>
  ...
  <entry date="2012-10-13T00:00:00">...</entry>
</entries>

И $dateBegin := '2012-10-09T13:00:00' и $dateEnd := '2012-10-12T00:00:00'. Я ищу эффективный способ получить записи в диапазоне от $dateBegin до $dateEnd, есть идеи?


person Rob    schedule 25.12.2012    source источник
comment
Отсортированы ли записи в документе XML по датам?   -  person Dimitre Novatchev    schedule 25.12.2012
comment
Какой процессор запросов вы используете? Производительность, как правило, сильно зависит от реализации.   -  person Leo Wörteler    schedule 25.12.2012


Ответы (3)


Используя подтвержденный Робом (OP) факт, что элементы entry отображаются отсортированными в XML-документе, это может быть быстрее:

for $dateBegin in xs:dateTime('2012-10-09T13:00:00'),
    $dateEnd in xs:dateTime('2012-10-12T00:00:00')
    return
            /*/*[xs:dateTime(@date) ge $dateBegin
               and
                . << /*/*[xs:dateTime(@date) gt $dateEnd][1]
                ]

Когда этот XQuery оценивается по предоставленному XML-документу:

<entries>
  <entry date="2012-10-09T12:09:09">...</entry>
  <entry date="2012-10-09T14:19:23">...</entry>
  ...
  <entry date="2012-10-13T00:00:00">...</entry>
</entries>

получен желаемый правильный результат:

<entry date="2012-10-09T14:19:23">...</entry>
person Dimitre Novatchev    schedule 25.12.2012
comment
Спасибо за этот ответ. К сожалению, это все еще занимает очень много времени, мой файл XML содержит почти 90000 записей. - person Rob; 26.12.2012
comment
@Rob, если дата начала находится в начале документа, а дата окончания - в конце документа, ничто не может помочь. То же самое, если обе даты находятся в самом конце документа. Если даты близки к старту, то это должно сработать быстро. Кроме того, если гарантируется, что начальная и конечная даты совпадают с датами в документе, можно использовать XSLT и ключи -- чтобы найти начальную и конечную записи -- это O(1). Если гарантируется, что доступ к последовательности по положению равен O(1) (например, в Saxon), можно написать двоичный поиск, чтобы найти начальную и конечную entry - person Dimitre Novatchev; 26.12.2012

Итак, наконец, я понял, что let $entries := //entry[(xs:dateTime(./@date/string()) ge $dateBegin) and (xs:dateTime(./@date/string()) le $dateEnd)] работает. Все еще интересно, существует ли лучшее решение.

person Rob    schedule 25.12.2012

У вас есть индекс диапазона для атрибута entry/@date, определенного для коллекции? Если нет, я считаю, что это ускорит запрос.

person hutchkintoot    schedule 24.02.2013