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