限制特定集合中文档中元素的范围索引

时间:2017-02-20 17:34:39

标签: marklogic marklogic-8

我们正在构建一个以ML作为后端的企业应用程序。应用程序中的许多屏幕都有下拉菜单,这些屏幕需要文档中不同的元素值。因此,我们为这些元素创建了元素范围索引,并准备好使用范围索引获取不同值的代码。

现在我们正在逻辑地将文档分成不同的集合 - 比如“basedata”集合,其中包含所有应用程序基础数据文档,“transactiondata”集合将所有传入/传出事务保存到我们的应用程序中。

现在要求将范围索引限制为仅基础数据收集文档而不是事务数据文档。

例如:如果我们有 localname =“entityName”的元素范围索引,我们不希望为文档中的entityName值构建范围索引交易数据收集。我们希望“entityName”的不同值仅在附加到basedata集合的文档中出现。

我们如何实现这一目标?

修改

感谢David和grtjn。

这是我们目前在java层中所做的事情:下面的代码正确返回了 entityName 字段的Distinct名称,该字段已创建了范围索引。

String valueOptionString = 
    " <search:options xmlns:search="http://marklogic.com/appservices/search">
        <search:values name="entityName">
            <search:range type="xs:string">
                <search:element name="entityName">
                </search:element>
            </search:range>
        </search:values>
    </search:options> ";    

QueryManager queryMgr = client.newQueryManager();
    QueryOptionsManager optionsMgr = client.newServerConfigManager().newQueryOptionsManager();
    optionsMgr.writeOptions("DistinctValues", new StringHandle(valueOptionString));

    ValuesDefinition vdef = queryMgr.newValuesDefinition("entityName", "DistinctValues");
    ValuesHandle vh = queryMgr.values(vdef, new ValuesHandle());

    for (CountedDistinctValue value : vh.getValues()) {
        System.out.println("Distinct value is :: " +
            value.get("xs:string", String.class));
    }

正如您所看到的,我没有在queryMgr.values()的任何位置设置集合;根据提供的建议,我尝试在 valueOptionString 中添加集合约束,但它不起作用。 这是正确的方法吗?还有其他出路

<search:options xmlns:search="http://marklogic.com/appservices/search">
<search:values name="createdBy">
    <search:range type="xs:string">
        <search:element name="createdBy"/>
    </search:range>
    <search:collection>
        <search:uri>basedaata</search:uri>
        <search:uri>tansactiondata</search:uri>
    </search:collection>
</search:values>
</search:options>

遇到错误:

Local message: /config/query write failed: Bad Request. Server Message: RESTAPI-INVALIDCONTENT: (err:FOER0000) Invalid content: Op
eration results in invalid Options: XDMP-VALIDATEUNEXPECTED: (err:XQDY0027) validate strict { $opt } -- Invalid node: Found text{"basedaata..."} but expected () at fn:doc("")

编辑2:

根据以下答案,我更新了我的代码,在可选查询中包含“additional-query”部分,以包含返回的不同值。但是,看起来其他查询部分被忽略并且未按预期工作

更新了可选查询:

 <search:options xmlns:search="http://marklogic.com/appservices/search">
    <search:values name="entityName">
        <search:range type="xs:string">
            <search:element name="entityName"/>
        </search:range>
    </search:values>
    <search:additional-query>
        <cts:collection-query xmlns:cts="http://marklogic.com/cts">
            <cts:uri>basedata</cts:uri>
            <cts:uri>DistinctValueTest</cts:uri>
        </cts:collection-query>
    </search:additional-query>
</search:options>

以下是我的文件。我还在字段entityName上有元素范围索引。

基础数据集合中的文档:

<?xml  version="1.0" encoding="UTF-8"?>
<entity>
    <entityName>Company</entityName>
    <createdBy>CompanyOwner</createdBy>
    <createdDate>2017-01-01T05:56:35.360Z</createdDate>
    <status>Active</status>
    <entityattributes>
        <entityattribute>
        </entityattribute>
    </entityattributes>
</entity>

现在创建了一个名为DistinctValueTest的测试集合,并在该集合中添加了一个用于测试目的的文档。

DistinctValueTest集合中的文档:

<?xml  version="1.0" encoding="UTF-8"?>
<entity>
    <entityName>DistinctValueTestEntity</entityName>
    <createdBy>DistinctValuteSystemNew</createdBy>
    <createdDate>2017-01-03T05:56:35.360Z</createdDate>
    <status>Active</status>
    <entityattributes>
        <entityattribute>
        </entityattribute>
    </entityattributes>
</entity>

当附加查询部分提供两个集合时,程序的输出为:Company,DistinctValueteSystemNew

<cts:collection-query xmlns:cts="http://marklogic.com/cts">
    <cts:uri>basedata</cts:uri>
    <cts:uri>DistinctValueTest</cts:uri>
 </cts:collection-query

但是如果我只在cts中提供“basedata”集合:uri它仍然显示输出为Company,DistinctValueteSystemNew,而不仅仅是公司

 <cts:collection-query xmlns:cts="http://marklogic.com/cts">
     <cts:uri>basedata</cts:uri>
 </cts:collection-query

2 个答案:

答案 0 :(得分:3)

不是为每个条件组合构建多个索引,而是在读取时组合索引。 cts:values函数采用第4个参数,该参数表示将减少将从中派生值的片段的查询。在你的情况下,它看起来像:

{{1}}

使用稍微更抽象的search:values函数和/v1/values REST端点可以实现类似的效果。

HTH!

答案 1 :(得分:1)

根据grtjn的回答和您更新的问题,一种直接的方法来限制您返回特定集合的值,并在您的选项中添加了additional-query

<search:options xmlns:search="http://marklogic.com/appservices/search">
  <search:values name="createdBy">
    <search:range type="xs:string"> 
      <search:element name="createdBy"/>
    </search:range>
  </search:values>
  <search:additional-query>
    <cts:collection-query xmlns:cts="http://marklogic.com/cts">
      <cts:uri>basedata</cts:uri>
      <cts:uri>transactiondata</cts:uri>
    </cts:collection-query>
  </search:additional-query>
</search:options>

使用该组选项向每个运行的查询添加additional-query