2016-01-20 38 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