如何基于元素名称和指定的父级构建字段范围索引

时间:2011-11-18 12:51:49

标签: xml marklogic

以下是我在数据库中的示例XML

<Device>
    <Name>device1</Name>
    <Sensors>
        <Sensor>
            <Name>sensor1</Name>
        </Sensor>
        <Sensor>
            <Name>sensor2</Name>
        </Sensor>
</Device>

我想为具有Device父元素的Name元素构建Field Range Index,但不为来自Sensor的Name元素构建{{1}}。根据字段配置规则,我不能只将Name元素添加到字段中并排除Sensors元素。 MarkLogic 5有什么解决方案吗?根据我的应用程序的要求,我无法转换文档和更改元素名称。

2 个答案:

答案 0 :(得分:2)

简单的回答是“不”。但当然有前进的方法。

如果您可以添加属性(但保持元素名称不变),则可以通过该方式约束字段,例如:

<Device>
  <Name _field="DeviceName">device1</Name>
  ...
</Device>

属性/值对可以是您想要的任何内容;你只需告诉字段定义,它是什么。一个好的做法可能是namespace-qualify属性,所以它显然是来自不同词汇的注释,例如:

<Device xmlns:field="http://example.com/field-annotations">
  <Name field:name="DeviceName">device1</Name>
  ...
</Device>

范围索引当前只能与元素值,属性值和字段值相关联。 Fields允许你从底层结构中抽象一点,但不像更通用的机制那样抽象。

有时使用的另一种技术(虽然我没有亲自尝试过这种方法)是使用两个数据库,一个更“逻辑”(例如,标准格式,未更改)和一个更database-optimized的数据库。 / p>

无论你决定什么方法,都需要做更多的工作。

如果我是你,我可能会写一个XSLT转换,可以应用于输入,另一个简单的转换原始未注释版本,如果我需要它。

annotate.xsl:

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:field="http://example.com/field-annotations">

  <xsl:import href="copy.xsl"/>

  <!-- Annotate Device/Name as a field -->
  <xsl:template mode="add-att" match="Device/Name">
    <xsl:attribute name="field:name" select="'DeviceName'"/>
  </xsl:template>

</xsl:stylesheet>

cleanup.xsl:

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:field="http://example.com/field-annotations">

  <xsl:import href="copy.xsl"/>

  <!-- Delete all field:* attributes -->
  <xsl:template match="@field:*"/>

</xsl:stylesheet>

copy.xsl:

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- Don't add any attributes by default -->
  <xsl:template mode="add-att" match="*"/>

  <!-- recursively copy elements -->
  <xsl:template match="*">
    <xsl:element name="{name()}" namespace="{namespace-uri()}">
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates mode="add-att" select="."/>
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <!-- copy attributes and child nodes -->
  <xsl:template match="@* | text() | comment() | processing-instruction()">
    <xsl:copy/>
  </xsl:template>

</xsl:stylesheet>

您可以在应用程序代码中使用annotate.xsl应用xdmp:xslt-invoke(),以便将文档插入数据库。或者,您可以将annotate.xsl配置为Information Studio流中的转换器。

如果要检索原始文档,只需调用:

xdmp:xslt-invoke("cleanup.xsl", doc("my-doc.xml"))

但是对于常规应用程序代码中的大多数情况,您不需要清理文档。因为,额外属性的存在很少会产生任何影响。

答案 1 :(得分:1)

从Marklogic 6开始,这正是路径范围索引旨在解决的问题:

http://developer.marklogic.com/blog/path-range-indexes

相关问题