Как отсортировать данные по значениям элемента с помощью функции cts:element-attribute-values ()?

#marklogic #marklogic-8 #marklogic-10

Вопрос:

ТРЕБОВАНИЕ : Как можно быстрее получить идентификаторы сотрудников (/Employee/@id), соответствующие запросу в порядке возрастания даты присоединения (/Employee/Дата присоединения).

СРЕДА : База данных MarkLogic насчитывает 1 миллион XML-файлов сотрудников

ЗАПРОС-1 [Выполняется очень медленно, но возвращает данные в правильном порядке]

 let $fullQuery :=
    cts:and-query((
        cts:directory-query("/employee/", "infinity"),
        cts:element-value-query(fn:QName("","DeptName"), "Sales", ("case-insensitive")),
        cts:element-value-query(fn:QName("","SubDeptName"), "Micro", ("case-insensitive"))
    ))
let $queryOptions := ("unfiltered", cts:index-order(cts:element-reference(fn:QName("","JoiningDate"),("type=dateTime")), "ascending"))
return cts:search(/Employee, $fullQuery, $queryOptions)!fn:string(./@id) (: Using ! to get id's in sorted order. This seems to affect performance quite heavily. :)
 

ЗАПРОС-2 [Выполняется очень быстро, но возвращает данные в неправильном порядке]

 let $fullQuery :=
    cts:and-query((
        cts:directory-query("/employee/", "infinity"),
        cts:element-value-query(fn:QName("","DeptName"), "Sales", ("case-insensitive")),
        cts:element-value-query(fn:QName("","SubDeptName"), "Micro", ("case-insensitive"))
    ))
let $queryOptions := ("concurrent")
return cts:element-attribute-values(xs:QName("Employee"), xs:QName("id"), (), $queryOptions, $fullQuery)
 

Как выполнить это ТРЕБОВАНИЕ, используя любой из двух вышеперечисленных подходов?

Комментарии:

1. Вы пробовали изменить путь к выражению $первого параметра cts:search? cts:search(/Employee/@id, $fullQuery, $queryOptions)

2. @Mads Хансен, я был бы удивлен, если бы это сработало, так как концептуально запросы значений элементов не будут соответствовать XPath /Employee/@id, поскольку атрибут id не имеет и не может иметь узлов элементов. В любом случае, я постараюсь дать вам знать.

3. Или добавьте этот путь после поиска вместо простого оператора сопоставления

4. @Мадс Хансен, если вы точно знаете, что это сработает, можете ли вы объяснить, почему?

5. Причина использования простого оператора сопоставления заключается в получении значений идентификаторов в ожидаемом отсортированном порядке. По какой-то причине я не получал значения идентификаторов в отсортированном порядке, используя /@id после выражения cts:search.

Ответ №1:

cts:value-co-occurrences позволит вам упорядочивать по одному индексу, одновременно возвращая значения из другого индекса.

напр.

 for $v in cts:value-co-occurrences(
  cts:element-reference(xs:QName("JoiningDate"),
  cts:element-attribute-reference(xs:QName("Employee"), xs:QName("id")),
  (), 
  $fullQuery
)
return $v/cts:value[2]/string(.)
 

Комментарии:

1. это работает! Как здесь работает сортировка? Сортируется ли результат только по первой ссылке? Гарантирует ли это, что данные всегда правильно сортируются по дате присоединения?

2. Результаты возвращаются в порядке индексации первой ссылки на индекс, да. В зависимости от того, какие параметры сортировки используются.