以下是我在数据库中的示例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有什么解决方案吗?根据我的应用程序的要求,我无法转换文档和更改元素名称。
答案 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开始,这正是路径范围索引旨在解决的问题: