2016-01-20 64 views
1

我有具有以下結構Marklogic搜索選項來限制搜索一個JSON嵌套屬性

{"scientist":{ 
     "username": "XXX", 
     "name":"XXXX" 
      ... 
    }, 
    "registrar":{ 
     "username": "YYY", 
     "name":"aaaaa" 
      ... 
    } 
    } 

我想限制搜索在如上述JSON搜索嵌套屬性JSON: - 想要搜索「註冊商/用戶名」..我試圖使用搜索-constraint「容器」..但無法執行搜索..以下是我的代碼,它似乎並沒有工作..

是否有任何其他機制的嵌套json字段搜索?

```

let $search := "(username:WHITEMK) AND (concept.registrar:)" 

let $options := 
    <options xmlns="http://marklogic.com/appservices/search"> 
    <constraint name="concept.registrar"> 
     <container> 
     <json-property>registrar</json-property> 
     </container> 
    </constraint> 
    <constraint name="username"> 
     <value> 
     <json-property>username</json-property> 
     <term-option>case-insensitive</term-option> 
     <term-option>wildcarded</term-option> 
     </value> 
    </constraint> 
    <return-facets>false</return-facets> 
    <return-values>false</return-values> 
    <return-constraints>false</return-constraints> 
    <return-frequencies>false</return-frequencies> 
    <return-qtext>false</return-qtext> 
    <search-option>unfiltered</search-option> 
    <search-option>unfaceted</search-option> 
    <search-option>format-json</search-option> 
    <search-option>score-simple</search-option> 
    </options> 

let $start := 1 
let $page-length :=10000 

return search:search($search, $options, $start, $page-length) 

```

感謝, 拉維

+0

我能夠通過添加字段個別嵌套的葉子。對於如要解決嵌套問題:在我上面的情況下,我加入註冊商/用戶名作爲現場..所以我的代碼看起來像下面 ''' <約束名= 「用戶名」> <字段名= 「concept_registrar_username」/> 不區分大小寫的 通配 ''' 但我想讓它足夠通用,所以我想創建所有葉節點的字段?任何方式使用約束容器達到 – Ravi

回答

0

我能得到一個更寬泛的版本而無需添加嵌套的領域是建立一個自定義的搜索選項,解析嵌套的JSON財產,並建立使用CTS搜索查詢:JSON-財產範圍查詢..
對於例如:讓我們假設你想尋找一些3級嵌套屬性

let $search := "(concept:orfs.aminoAcids.predictedMatureSeqs.domains.heavyChainIsoType:igg1)" 

使用自定義分析器我能如果有人有興趣下面這個變換以下

<cts:json-property-scope-query xmlns:cts="http://marklogic.com/cts"> 
<cts:property>orfs</cts:property> 
<cts:json-property-scope-query> 
<cts:property>aminoAcids</cts:property> 
<cts:json-property-scope-query> 
<cts:property>predictedMatureSeqs</cts:property> 
<cts:json-property-scope-query> 
<cts:property>domains</cts:property> 
<cts:json-property-scope-query> 
<cts:property>heavyChainIsoType</cts:property> 
<cts:word-query> 
<cts:text xml:lang="en">igg1</cts:text> 
<cts:option>case-insensitive</cts:option> 
<cts:option>punctuation-insensitive</cts:option> 
<cts:option>whitespace-insensitive</cts:option> 
<cts:option>wildcarded</cts:option> 
</cts:word-query> 
</cts:json-property-scope-query> 
</cts:json-property-scope-query> 
</cts:json-property-scope-query> 
</cts:json-property-scope-query> 
</cts:json-property-scope-query> 

是代碼自定義解析器

xquery version "1.0-ml"; 
module namespace gbrsso="http://marklogic.com/gbrs/modules"; 
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy"; 
(: 
    This module tries to build a custom constraint.. and takes into account the nested query as well 
    for eg: Concept:registrar.username:mamidrx 
:) 

(: This is parse function which is invoked my marklogic when it sees the custom constraing :) 
declare function gbrsso:parse($constraint-qtext as xs:string, $right as schema-element(cts:query)) as schema-element(cts:query){ 
let $log := xdmp:log("Constraint-qtext : " || $constraint-qtext) 
let $log := xdmp:log("$right : " || fn:string($right//cts:text/text())) 
let $queryText := fn:string($right//cts:text/text()) 
let $qparts := fn:tokenize($right//cts:text/text(), ":") 
let $queryText := $qparts[last()] 
let $log := xdmp:log("$queryText : " || $queryText) 

    let $qpartsCnt := fn:count($qparts) 

    let $query := 
     if(fn:count($qparts) = 1) then 
     <root>{ 
      cts:word-query($queryText, ("case-insensitive", "wildcarded", "punctuation-insensitive", "whitespace-insensitive")) 
      }</root>/* 
     else 
     <root>{ 
      let $qparts := fn:tokenize($qparts[1],"\.") 
      let $endPart := $qparts[last()] 
      (: remove the last part in sequence as we need to create word query with it :) 
      let $qparts := fn:remove($qparts, fn:count($qparts)) 
      let $queryExp := 
      if(fn:count($qparts) = 0) then (: checks if it is nested... :) 
       cts:json-property-scope-query($endPart, cts:word-query($queryText, ("case-insensitive", "wildcarded", "punctuation-insensitive", "whitespace-insensitive"))) 
      else 
       let $xy := cts:json-property-scope-query($endPart, cts:word-query($queryText, ("case-insensitive", "wildcarded", "punctuation-insensitive", "whitespace-insensitive"))) 
       return gbrsso:buildQuery($xy, $qparts) 

      return $queryExp 
     }</root>/* 

    return $query 

}; 
1

截至今天指出,討論列表,它應該如果所包含的約束之前,前綴的容器中工作,如在:

let $search := "concept.registrar:username:WHITEMK" 

作爲一個腳註,當你嘗試要理解查詢文本如何被解析,有時候首先使用search:parse()更容易。

很好,你找到了一個短期的解決方法。我希望這有助於長期解決方案。

+0

這仍然不起作用..所以用於搜索:解析。並且它也失敗..給我以下異常...我使用Marklogic 8 ' In /MarkLogic/appservices/search/ast.xqy on line 1061 在ast:handle-container-constraint( concept.registrar r ...,map:map()) ' – Ravi

+0

您的評論是通過亂碼發出的,也就是說,我沒有在測試中看到該錯誤。帳戶,請提供有關如何重現問題的詳細信息。 – ehennum