在MarkLogic中检索不带范围索引的元素值

在MarkLogic中检索不带范围索引的元素值,marklogic,Marklogic,我在MarkLogic中有以下情况。我有一个包含大量文档的数据库,每个文档包含数百个字段。现在让我们假设,对于其中一个字段,我希望使用cts:search从一大组文档中检索所有值。我有什么选择 显然,我可以在这里使用范围索引。然而,当我探索我的数据集时,这意味着我必须将范围索引应用于我的所有字段,这似乎。。。。太过分了。此外,我完全同意每个查询都需要一点时间 因此,我尝试运行一个简单的cts:search查询:cts:search//Cost,cts:collection querymyColl

我在MarkLogic中有以下情况。我有一个包含大量文档的数据库,每个文档包含数百个字段。现在让我们假设,对于其中一个字段,我希望使用cts:search从一大组文档中检索所有值。我有什么选择

显然,我可以在这里使用范围索引。然而,当我探索我的数据集时,这意味着我必须将范围索引应用于我的所有字段,这似乎。。。。太过分了。此外,我完全同意每个查询都需要一点时间

因此,我尝试运行一个简单的cts:search查询:cts:search//Cost,cts:collection querymyCollection。这个函数返回我感兴趣的元素的值和元素,当我查找少于10k个文档时,它可以正常工作。然而,当我探索一个包含1m个文档的集合时,我得到一个错误,这表明MarkLogic实际上是在检索XML节点并将其返回到查询控制台之前打开所有文档

有没有办法更改此查询,使其至少返回一个结果


我尝试过运行未筛选的搜索并使用xdmp:eval隔离事务,但到目前为止没有结果。

我相信Taskbot--将有助于避免填充扩展的树缓存,因为它将工作拆分为用户定义的事务数。在没有范围索引的情况下,ML需要加载每个文档以获取值,这是正确的。Taskbot至少可以避免在一次事务中加载一百万个文档,从而确保您返回结果

一般来说,非常大的查询需要计算平均值或趋势,一个样本就足够了。您可以使用cts.search和score random选项进行随机抽样。这会导致搜索的排序,这是搜索引擎的术语,但当然,这实际上是一个随机查询,因此前10000个项目将是一个随机样本,取决于您的查询条件


但是,如果您需要处理整个数据集或数据集,则taskbot、corb、范围索引或在摄取时具体化数据都是可选的。

一个选项是执行,它将把工作分散到具有多个线程的单个模块执行中

这将避免出现扩展树缓存错误的机会,因为每个文档都在单个模块执行中进行处理,然后将结果收集到一个文件中。您还可以启用该选项,它允许您处理一组非常大的URI,而不必将它们全部放在JVM的内存中

CORB作业将选择集合中文档的所有URI,并在集合中包含要报告的元素。返回这些成本要素的值。将作业配置为使用将流程模块的结果写入单个文件,然后使用对值进行排序和重复数据消除

下面是一个示例CORB选项文件,用于配置作业以实现所需目标。您需要调整以连接到数据库

# 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=

这听起来像是一个经典的“数据仓库BI查询”。在这种情况下,可以应用传统数据仓库数据库的概念。这类BI查询的示例是使用“列查询”,例如,在所有“行”上聚合,但被一个或几个“列”分割,即经典的“所有行的X的总和/最小值/最大值/平均值” 因此诞生了列存储数据库和现代数据湖变体Presto、Athena,以及某种程度上的Hadoop。MarkLogic方法最常用于范围索引的使用。你提到你必须对我所有的字段应用索引,但你也说聚合函数是“一个字段”。这就是人们可能错误地将索引的使用混为一谈的地方。我相信你的情况是这样的 候选文档的查询很复杂,可能有1000个字段,但是 B计算所需的值为一个或几个字段

您可以通过在字段B上放置目标范围查询或类似查询(包括语义索引)来解决此问题,然后使用通用索引,或者如果需要,使用一些针对目的a的精选增强功能。结果可能完全或主要由索引解决

数据仓库技巧2 在不同的存储上创建临时数据库和林。 预处理源数据并对其进行过滤,可能会重新规范化为一个简单的最小表示形式,使用尽可能少的单独元素/属性类型。 对此提出质疑 如果有足够的ram,这可以完全在内存中使用映射或数组来完成

妥协; 使用多个通行证- 第一步通过一个理想情况下完全可索引解析的查询来识别包含感兴趣的值的文档ID。如果没有,则按上述方法分批处理。 文档ID可能适合会话或服务器范围变量。 使用精确的cts:search或xpath表达式仅查询必需的值,该表达式仅检索作为序列的1值。拥有
文档ID的预先强制查询计划不需要仅打开给定的“可能文档”。ID足以直接针对任何其他索引解析和/或查询文档包含。

您能否详细说明您希望对该搜索结果做什么?计算平均值、最小值、最大值、中值、MODU等。只需简单的数据探索。