Marklogic搜索选项以限制对JSON嵌套属性的搜索

Marklogic搜索选项以限制对JSON嵌套属性的搜索,marklogic,Marklogic,我有一个json,它的结构如下 {"scientist":{ "username": "XXX", "name":"XXXX" ... }, "registrar":{ "username": "YYY", "name":"aaaaa" ... } } 我想将搜索限制为在上面的json中搜索嵌套属性,例如:--想搜索“registrator/username”

我有一个json,它的结构如下

{"scientist":{
         "username": "XXX",
         "name":"XXXX"
          ...
    },
    "registrar":{
      "username": "YYY",
         "name":"aaaaa"
          ...
    }
   }
我想将搜索限制为在上面的json中搜索嵌套属性,例如:--想搜索“registrator/username”。。我试图使用搜索约束“容器”。。但无法进行搜索。。下面是我的代码,它似乎不起作用

嵌套json字段搜索还有其他机制吗

```

let$search:=(用户名:WHITEMK)和(concept.registrator:)
let$options:=
登记员
用户名
不区分大小写
通配符
假的
假的
假的
假的
假的
未过滤
未固定
格式json
得分简单
让$start:=1
设$page length:=10000
返回搜索:搜索($search,$options,$start,$page length)
```

谢谢,
Ravi

正如今天在讨论列表中所指出的,如果在包含的约束之前加上容器前缀,应该可以工作,如:

let $search := "concept.registrar:username:WHITEMK"
作为一个脚注,当您试图理解如何解析查询文本时,首先使用search:parse()有时会更容易


很好,你找到了短期的解决办法。我希望这对长期解决方案有所帮助。

我可以通过构建自定义搜索选项获得更通用的版本,而无需添加嵌套字段,该选项解析嵌套的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>

ORF
氨基酸
预测饱和度
领域
重链型
igg1
不区分大小写
标点不敏感
不区分空格
通配符
如果有人感兴趣,下面是定制解析器的代码

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

};
xquery版本“1.0-ml”;
模块名称空间gbrsso=”http://marklogic.com/gbrs/modules";
导入模块命名空间搜索=”http://marklogic.com/appservices/search“在“/MarkLogic/appservices/search/search.xqy”;
(:
此模块尝试构建自定义约束,并考虑嵌套查询
例如:概念:注册器。用户名:mamidrx
:)
(:这是一个parse函数,当它看到自定义约束时会调用我的marklogic:)
将函数gbrsso:parse($constraint-qtext作为xs:string,$right作为模式元素(cts:query))声明为模式元素(cts:query){
让$log:=xdmp:log(“约束qtext:| |$Constraint qtext”)
让$log:=xdmp:log(“$right:| | fn:string($right//cts:text/text()))
让$queryText:=fn:string($right//cts:text/text())
让$qparts:=fn:tokenize($right//cts:text/text(),“:”)
让$queryText:=$qparts[last()]
让$log:=xdmp:log($queryText:| |$queryText)
let$qpartsCnt:=fn:count($qparts)
让$query:=
如果(fn:count($qparts)=1),则
{
cts:word查询($queryText,(“不区分大小写”、“不区分通配符”、“不区分标点符号”、“不区分空格”))
}/*
其他的
{
让$qparts:=fn:tokenize($qparts[1],“\”)标记化
让$endPart:=$qparts[last()]
(:删除序列中的最后一部分,因为我们需要使用它创建word查询:)
让$qparts:=fn:remove($qparts,fn:count($qparts))
让$queryExp:=
如果(fn:count($qparts)=0),则(:检查它是否嵌套…:)
cts:json属性范围查询($endPart,cts:word查询($queryText,(“不区分大小写”、“通配符”、“不区分标点符号”、“不区分空格”))
其他的
let$xy:=cts:json属性范围查询($endPart,cts:word查询($queryText,(“不区分大小写”、“通配符”、“不区分标点”、“不区分空格”))
返回gbrsso:buildQuery($xy,$qparts)
返回$queryExp
}/*
返回$query
};

我可以通过为单个嵌套叶添加字段来绕过嵌套问题。。例如:在我上面的例子中,我添加了registrator/username作为一个字段。。所以我的代码看起来像下面的``不区分大小写的通配符``但是我想让它足够通用,所以我想为所有叶节点创建字段?使用仍然不起作用的约束容器实现的任何方法。。所以使用搜索:解析。而且它也失败了。。给我以下的例外。。。我在ast:handle container constraint(r..,map:map())的第1061行中使用了Marklogic 8`In/Marklogic/appservices/search/ast.xqy`您的评论被打乱了。也就是说,我在测试中没有看到这个错误。如果您有客户支持帐户,请提交一个bug,并说明如何重现问题。
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

};