【问题标题】:Marklogic index childrenMarklogic 索引子项
【发布时间】:2015-02-20 21:47:29
【问题描述】:

是否可以对子元素进行索引?

我的数据是这样设置的

    <schedule id="ID_HERE" lang="LANGUAGE">
    <scheduleItem id="CHILD_NODE_ID" lang="eng">
        <dateTime>
            2015-01-19T00:00:09-00:00
        </dateTime>
    </scheduleItem>
    <scheduleItem id="CHILD_NODE_ID1" lang="eng">
        <dateTime>
            2015-01-19T00:00:09-00:00
        </dateTime>
    </scheduleItem>
    <scheduleItem id="CHILD_NODE_ID2" lang="eng">
        <dateTime>
            2015-01-19T00:00:09-00:00
        </dateTime>
    </scheduleItem>
</schedule>

我的数据库中有多个时间表。

我正在尝试获取适合搜索结果的 scheduleItems 的数量 - 例如:/@lang = eng/dateTime &lt; 2015-01-19T00:00:00 的所有 scheduleItems 的计数

我正在使用 search:search 来查询这些项目,但是搜索的结果/@total 是日程安排的数量,而不是日程安排项目的数量。

我还发现,当我执行xdmp:estimate(/schedule/scheduleItem) 时,它返回的是计划数,而不是 scheduleItem 数。

fn:count() 返回正确的数字,但如果 fn:count() 速度慢且不使用索引,我想避开它。

有没有办法使用xdmp:estimate()search:search() 获取 scheduleItems 的数量?

我正在研究字段范围索引

【问题讨论】:

  • 我还尝试了search:search() 选项为&lt;return-results&gt;false&lt;/return-results&gt; 这只返回了计划的数量
  • 您可以在&lt;scheduleItem&gt; 上创建片段根,但一般来说,片段根不是一个好主意,除非一些非常特殊的场景。您需要提供有关数据库中内容的更多信息,以及该应用程序为某人所做的确切工作,以确定这是否合适。
  • @wst 据我了解,片段根会使我的&lt;scheduleItem&gt;s 像文档一样被索引?缺点是什么?将每个 &lt;scheduleItem&gt; 放在单独的文档中会不会更糟? (它们大约有 430 个字符长)

标签: xml indexing xquery marklogic


【解决方案1】:

MarkLogic 默认索引所有元素。这里的问题是您将文档视为表格。文档的行为更像行。我建议为每个 scheduleItem 元素创建一个文档。该计划可以是一个 URI 前缀,创建一个虚拟目录,如 "/schedules/"||$id||"/"。平均为 430-B 的文档会有点小,但大小不如设计文档结构以使其与您的应用程序相匹配。

您还可以考虑scheduleItem 上的片段根。但从长远来看,我认为您最好使用多个文档。

【讨论】:

  • 片段根有什么缺点?我~would~希望将 scheduleItems 保留为 schedule 的子项,因为我将添加和删除整个日程表。但将 scheduleItems 拆分为单独的文件并不难。
  • 我对片段根的主要反对意见是它们增加了复杂性。遍历像/schedule/scheduleItem 这样的XPath 的成本发生了变化,因为您正在跨越片段边界并且片段驱动I/O 操作。编写意外加载所有子片段的 XPath 非常容易,这可能是大量 I/O。我在其他一些帖子中写过这个:stackoverflow.com/search?q=%5Bmarklogic%5D+fragment+root 可能会有所帮助。或者进行实验:您以后可以随时更改结构。
  • 您提到了范围索引:如果您启用位置感知选项并且要运行的查询集非常有限,这可能是一个选项。基本上你会直接从cts:values 中提取所有结果,而不是使用search:search 或XPath。
【解决方案2】:

我还建议拆分文档,但如果您愿意创建范围索引,您可能可以执行以下操作:

fn:sum(
  for $v in cts:element-attribute-values(
    xs:QName('scheduleItem'),
    xs:QName('lang'),
    (),
    "item-frequency"
  )
  return cts:frequency($v)
)

这将从范围索引的值词典中提取所有唯一值,从索引中获取所有值的计数,并且只需要在运行时进行求和即可找到总数。

cts:*-values 函数还采用一个额外的参数来限制例如包含特定日期范围内的 scheduleItems 的计划。这将包括误报,但如果您不将文档拆分为单独的 scheduleItems,或者按照 Michael 的建议应用片段根。

HTH!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 2015-04-15
    • 2021-11-25
    相关资源
    最近更新 更多