2017-02-20 63 views
1

我們正在構建一個以ML作爲後端的企業應用程序。應用程序中的許多屏幕都有下拉,這要求文檔中的元素具有不同的值。因此,我們爲這些元素創建了元素範圍索引,並讓代碼準備好使用範圍索引獲取不同的值。限制特定集合中文檔內元素的範圍索引

現在我們正在邏輯上將文檔分隔到不同的集合中 - 比如包含所有應用基礎數據文檔的「基礎數據」集合和保存所有傳入/傳出事務到我們的應用程序的「事務數據」集合。

現在需要將範圍索引限制爲僅基礎數據收集文檔而不是交易數據文檔。

例如:如果我們有一個元素的範圍索引的localName =「的entityName」我們不想範圍內指數爲存在於交易數據的收集文件的entityName值之上。我們希望僅在連接到基本集合的文檔中出現「entityName」的不同值。

我們該如何做到這一點?

編輯:

感謝大衛和grtjn。

這是我們現在正在做在java層:下面的代碼正確返回不同的名稱爲它創造了一種介於指數領域的entityName

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()設置收集的任何地方;基於提供我嘗試添加集合約束的int 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-查詢「部分以包含返回的不同值。但是它的外觀額外的查詢部分被忽略如預期

更新可選查詢是不工作:

<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元素範圍索引..

文檔basedata集合:

<?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> 

的程序的輸出是:公司,DistinctValueteSystemNew當兩個集合的額外的查詢部如果供給

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

但是我只在cts:uri中提供「基礎數據」集合,它仍然顯示爲公司,DistinctValueteSystemNew的輸出,而不僅僅是公司

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

將編輯部分放在單獨的問題中可能會更好.. – grtjn

回答

3

與其爲每個標準組合構建多個索引,不如在讀取時組合索引。 cts:values函數接受第四個參數,該參數代表將從中派生出片段的片段。在你的情況下,它看起來是這樣的:

cts:values(
    cts:element-reference(xs:QName("entityName")), 
(), 
(), 
    cts:collection-query("basedata") 
) 

類似的效果可與稍微抽象search:values功能來實現,而/v1/values REST端點。

HTH!

+0

感謝David/grtjn。我嘗試了上面的內容,並用我遇到的問題更新了我的問題。請告訴我。提前致謝。 – nocoder

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添加到使用該選項集運行的每個查詢中。

+0

附加查詢是處理這個問題的一種方法,但是您的Java代碼將調用封面下的'/ v1/values/createdBy'。該REST端點將接受'collection'請求參數,'q'參數和'structuredQuery'參數,所有這些參數都可以用來獲得與附加查詢相同的效果,但以更加動態的方式。應該有辦法告訴'queryMgr'對象通過額外的約束。 (周圍的任何人可能知道如何?) – grtjn

+0

@grtjn 不能按預期工作。更新了我原來的問題。請檢查編輯2. – nocoder

+0

@Dave關於我在上面的問題的編輯2中遇到的問題的任何更新?謝謝你的幫助。 – nocoder

相關問題