Получение значений элементов без индексов диапазона в MarkLogic - PullRequest
0 голосов
/ 06 июля 2018

У меня следующая ситуация в MarkLogic. У меня есть база данных с большим количеством документов, каждый из которых содержит сотни полей. Теперь предположим, что для одного из полей я хочу получить все значения из большого набора документов (используя cts:search). Какие у меня варианты?

Очевидно, я мог бы использовать индекс диапазона здесь. Однако, когда я исследую свой набор данных, это будет означать, что я должен применить индексы диапазона ко всем моим полям, что кажется ... излишним. Кроме того, я прекрасно справляюсь с каждым запросом, который занимает немного времени.

Итак, я попытался выполнить простой поисковый запрос cts: cts:search(//Cost, cts:collection-query("myCollection)). Эта функция возвращает значение (и элемент) интересующего меня элемента и прекрасно работает, когда я ищу менее 10 тыс. Документов. Однако, когда я исследую набор с документами 1м, я получаю ошибку XDMP-EXPNTREECACHEFULL , которая предполагает, что MarkLogic фактически открывает все документы перед извлечением узла XML и возвращает его в мой запрос-консоль.

Есть ли способ изменить этот запрос, чтобы он по крайней мере возвращал результат?

Я пытался запустить нефильтрованный поиск и использовать xdmp:eval для изоляции транзакции, но пока безрезультатно.

Ответы [ 3 ]

0 голосов
/ 06 июля 2018

Как правило, очень большие запросы должны вычислять средние значения или тренды, и выборка является адекватной и уместной. Вы можете использовать cts.search () с опцией «score-random», чтобы сделать случайную выборку. Это приводит к тому, что порядок «поиска» (это терминология поисковой системы - но, конечно, это действительно запрос) является случайным, поэтому первые 10000 элементов будут случайной выборкой в ​​зависимости от условий вашего запроса.

Но если вам нужно обработать весь набор данных или набор данных, то все это могут быть Taskbot, Corb, Range-Indexing или материализация данных при получении.

0 голосов
/ 07 июля 2018

Одним из вариантов может быть выполнение задания CORB , которое разделит работу на отдельные исполнения модуля с несколькими потоками.

Это позволило бы избежать вероятности ошибок расширенного кэша дерева, поскольку каждый документ обрабатывается в одном модуле, а результаты затем собираются в файл. Вы также можете включить опцию DISK-QUEUE , которая позволяет обрабатывать чрезвычайно большой набор URI без необходимости помещать их все в память в JVM.

Задание CORB выберет все URI документов, которые находятся в коллекции и содержат элемент, о котором вы хотите сообщить в URIS-MODULE . МОДУЛЬ ПРОЦЕССА возвращает значения из этих Cost элементов. Сконфигурируйте задание, чтобы записать результаты модуля процесса в один файл, используя PROCESS-TASK , а затем используйте POST-BATCH-TASK для сортировки и дедупликации значений.

Ниже приведен пример файла опций CORB для настройки работы для достижения желаемого. Вам нужно настроить XCC-CONNECTION-URI для подключения к вашей базе данных.

# how to connect to the database
XCC-CONNECTION-URI=xcc://myUsername:myPassword@localhost:8200

# An inline XQuery module to find the URIs of docs that have a Cost element and are in the myCollection
URIS-MODULE=INLINE-XQUERY|declare variable $URIS := cts:uris("", (), cts:and-query(( cts:collection-query("myCollection"), cts:element-query(xs:QName("Cost"), cts:true-query()) )) ); count($URIS), $URIS

# for every URI, extract and return the value of the Cost element(s)
PROCESS-MODULE=INLINE-XQUERY|declare variable $URI as xs:string external; fn:doc($URI)//Cost/string()

# write the results of the process module execution to a file
PROCESS-TASK=com.marklogic.developer.corb.ExportBatchToFileTask

# the name of the output file to write (use full path, or also use EXPORT-FILE-DIR)
EXPORT-FILE-NAME=cost-values.txt

# after batch processing is complete, modify the output file with a post-batch-task
POST-BATCH-TASK=com.marklogic.developer.corb.PostBatchUpdateFileTask

# sort and dedup the values in the export file
EXPORT-FILE-SORT=ascending|distinct

# how many threads you want processing the docs
THREAD-COUNT=10

DISK-QUEUE=true
# A location to store temporary files required for the disk queue, sorting and dedup, etc. (default is Java temp dir)
#TEMP-DIR=/temp

# Override the TEMP-DIR location with a different path to be used for the DISK-QUEUE
#DISK-QUEUE-TEMP-DIR=
0 голосов
/ 06 июля 2018

Я полагаю, что Taskbot - https://github.com/mblakele/taskbot - поможет избежать заполнения кеша расширенного дерева, поскольку он разбивает работу на определенное пользователем количество транзакций. Вы правы в том, что ML должен загружать каждый документ, чтобы получить значения при отсутствии индекса диапазона. Taskbot по крайней мере гарантирует, что вы получите результаты обратно, избегая, например ,. загрузка миллиона документов за одну транзакцию.

...