Короткий ответ заключается в том, что cts:and-query(())
не имеет собственных затрат, но запрос коллекции будет быстрее, чем ваше выражение для поиска. Я бы не использовать для поиска выражение на всех, так что я бы написать это как:
cts:search(collection(), cts:collection-query($journal-collection))
Чем дольше ответ, что ваш может проверить это довольно легко, и получить хорошую информацию от xdmp:plan
и «xdmp: запрос -meters`. Вы также можете использовать профилирование запросов.
Начнем с вставки некоторых тестовых документов. При этом используется https://github.com/mblakele/taskbot
(: insert 500k test documents. :)
import module namespace tb="ns://blakeley.com/taskbot"
at "taskbot.xqm" ;
tb:list-segment-process(
(: Total size of the job. :)
1 to 500 * 1000,
(: Size of each segment of work. :)
500,
"test/asset",
(: This anonymous function will be called for each segment. :)
function($list as item()+, $opts as map:map?) {
(: Any chainsaw should have a safety. Check it here. :)
tb:maybe-fatal(),
let $type-list := ('mj', 'pj', 'aj', 'bj', 'cj', 'dj')
let $type-count := count($type-list)
for $i in $list
let $idx := 1 + xdmp:random($type-count - 1)
let $type as xs:string := subsequence($type-list, $idx, 1)
return xdmp:document-insert(
"test/"||$type||"/"||$i,
element article {
element id { $type||$i },
element type { $type },
element { $type } { $i },
element issue { 1 + xdmp:random(99) },
element article { 1 + xdmp:random(999) },
(1 to xdmp:random(9)) ! element article-ref {
xdmp:random(1000) } },
xdmp:default-permissions(),
($type)),
(: This is an update, so be sure to commit each segment. :)
xdmp:commit() },
(: options - not used in this example. :)
map:new(map:entry('testing', '123...')),
(: This is an update, so be sure to say so. :)
$tb:OPTIONS-UPDATE)
бездельничать и ждать документов для загрузки. Вы можете проверить ErrorLog.txt
, чтобы увидеть прогресс или обновить статус базы данных. Или просто наблюдайте за своими процессорами.
После загрузки эти тестовые документы включают в себя много избыточности. Это позволяет нам проверять различные способы получения документов. Вот пример, чтобы посмотреть на:
<?xml version="1.0" encoding="UTF-8"?>
<article>
<id>mj192462</id>
<type>mj</type>
<mj>192462</mj>
<issue>31</issue>
<article>432</article>
<article-ref>589</article-ref>
<article-ref>812</article-ref>
<article-ref>316</article-ref>
<article-ref>512</article-ref>
<article-ref>380</article-ref>
</article>
Теперь я предпочитаю оставить первый cts:search
параметр как collection()
и сделать все, что в КТС: параметр запроса. Это более композитно и избегает любого соблазна вытеснить границы поисковых выражений. Поэтому я бы начал с тестирования, что cts:search(//mj, cts:and-query(()))
эквивалентен cts:search(collection(), cts:element-query(xs:QName('mj'), cts:and-query(())))
. Использование 7.0-4.1 и xdmp:plan
Я вижу, что они оба используют один и тот же поиск, который мы можем сокращать как OR(element(mj), link-child(descendant(element(mj))))
.
<qry:final-plan>
<qry:and-query>
<qry:or-two-queries>
<qry:term-query weight="0">
<qry:key>213142789040258053</qry:key>
<qry:annotation>element(mj)</qry:annotation>
</qry:term-query>
<qry:term-query weight="0">
<qry:key>11205365121816230941</qry:key>
<qry:annotation>link-child(descendant(element(mj)))</qry:annotation>
</qry:term-query>
</qry:or-two-queries>
</qry:and-query>
</qry:final-plan>
Обратите внимание, как нет ничего в плане, соответствующий вашему cts:and-query(())
? Это потому, что это нок. Реальная работа в запросе, например cts:search(/medicalJournal, cts:and-query(()))
, выполняется путем обработки поискового выражения /medicalJournal
. Это может помочь объяснить, почему я предпочитаю оставлять выражение для поиска как collection()
и соответствовать параметру cts:query
.
Термин интересный, но не будем вдаваться в него сейчас.
Вместо этого давайте посмотрим на некоторые другие способы добраться до mj
статей. Мы можем запросить сбор mj
или элементы, где type[.='mj']
, или запрос каталога на test/mj/
.
collection('mj')
cts:search(collection(), cts:collection-query('mj'))
cts:search(collection(), cts:element-value-query(xs:QName('type'), 'mj')
cts:search(collection(), cts:directory-query('test/mj/', 'infinity'))
Проверка xdmp:plan
выхода для каждого, мы видим, что qry:final-plan
показывает два term-query
просмотра для первых двух форм. Это очень похоже на element-query
на mj
, но не всегда на тех же условиях. Затем мы видим один за последние три. Термин ищет сложность запросов к диску, поэтому мы можем сказать, что запрос элемента в два раза сложнее, чем запрос коллекции.
Это в значительной степени отвечает на ваш вопрос, я думаю: cts:search(collection(), cts:collection-query('mj'))
может быть быстрее, чем cts:search(collection(), cts:element-query(xs:QName('mj'), cts:and-query(())))
, потому что он меньше поисков терминов.
Но давайте продолжим работу с последними тремя и посмотрим, есть ли какая-либо причина использовать ту или иную из трех последних альтернатив. Поиск коллекции и поиск в каталоге используют URI: соответственно URI коллекций и URI каталога. Они довольно сильно оптимизированы, поэтому мы можем ожидать, что они будут быстрее, чем поиск по элементам.
Посмотрим, можем ли мы доказать это, используя xdmp:query-meters
. Запуск каждый из последних трех выражений в форме, как это:
xdmp:describe(
cts:search(collection(), cts:collection-query('mj')))
, xdmp:query-meters()
Для этого упражнения внимания на то, что xdmp:query-meters
говорит о кэше дерева и обращениях в кэше списка и промахах. Не обращайте слишком много внимания на elapsed-time
, потому что это будет зависеть от того, сколько данных индекса кэшировано, и мы не можем это контролировать. В любом случае вы должны увидеть те же общие удары дерева и промахи со всеми тремя запросами. Я видел по 9 для каждого, но важно то, что нет никакой разницы, потому что результаты одинаковы. Но кеш-листы списков и пропуски складываются по-разному. С коллекцией или каталогом она равна количеству стендов в базе данных: в моем случае 3. Но для элемента-значения это вдвое больше числа трибун: в моем случае 6. Таким образом, все остальные равны, поиск по элементам-значения рискует сделать дважды много ввода-вывода. И все остальное не равно: в URI-поисках меньше вероятность ввода каких-либо операций ввода-вывода, потому что их индексы имеют тенденцию оставаться в памяти все время.
Мы можем заключить, что, хотя ни один из других методов не очень медленный, поиск по URI коллекции или URI каталога является лучшим.
Отличный отклик. Большое спасибо. – callow
Реализация 'cts: search' в JavaScript (ну,' cts.search') в предстоящей версии MarkLogic 8 фактически удаляет первый параметр и по умолчанию используется эквивалент 'cts: search (fn: collection() , $ query, $ options) '. –