我想将一个使用存储桶(bucketed search)的旧XQuery示例“转换”为JSearch:
import module namespace search =
"http://marklogic.com/appservices/search"
at "/MarkLogic/appservices/search/search.xqy";
declare variable $options := <options xmlns="http://marklogic.com/appservices/search">
<constraint name="height">
<range type="xs:double" facet="true">
<bucket ge="1.9" name="supertall">1.90m + </bucket>
<bucket lt="1.9" ge="1.7" name="tall">1.70m - 1.90m</bucket>
<bucket lt="1.7" ge="1.2" name="normalish">1.20m - 1.70m</bucket>
<bucket lt="1.2" name="short">0m - 1.20m</bucket>
<facet-option>limit=20</facet-option>
<json-property>height</json-property>
</range>
</constraint>
</options>;
let $results := search:search("height:short", $options)
for $facet in $results/search:facet
return $results;
以上允许定义桶以及允许使用'height'作为搜索语法的一部分,这意味着search:search('height:short')
之类的搜索工作正常。
不幸的是我无法使JSearch版本正常工作,这就是我尝试过的:
var jsearch = require('/MarkLogic/jsearch');
jsearch.documents(
jsearch.facet('Height', 'height').groupInto([
jsearch.bucketName('short'), 1.60,
jsearch.bucketName('normal'), 1.90,
jsearch.bucketName('tall'), 4.00
]))
.where(cts.parse('height:short'))
.result();
上面的代码返回:
{ “结果”:null, “估计”:0 }
我还试图添加对JSON属性'height'的引用,但这也不起作用:
var jsearch = require('/MarkLogic/jsearch');
var reference = { height: cts.jsonPropertyReference('height') };
jsearch.documents(
jsearch.facet('Height', 'height').groupInto([
jsearch.bucketName('short'), 1.60,
jsearch.bucketName('normal'), 1.90,
jsearch.bucketName('tall'), 4.00
]))
.where(cts.parse('height:short', reference))
.result();
然而,当我删除.where()
约束时,我的生成桶很好。有什么建议吗?
答案 0 :(得分:1)
我相信我找到了解决方法。高度值是数字,在我的JSearch查询中,我试图将字符串'short'与这些数字匹配。为了克服这个问题,我不得不使用一个回调函数,该函数已在本页http://docs.marklogic.com/cts.parse
中记录基本上,解决方案是使用一组cts查询构造函数(cts.andQuery和cts.jsonPropertyRangeQuery)创建自己的查询。解决方案现在看起来像这样:
var jsearch = require('/MarkLogic/jsearch');
var short = 1.60;
var normal = 1.80;
var tall = 1.90;
var refCallback = function(operator, values, options) {
if (values === 'short') {
return cts.jsonPropertyRangeQuery('height', '<=', short)
} else if (values === 'normal') {
return cts.andQuery([
cts.jsonPropertyRangeQuery('height', '>=', normal),
cts.jsonPropertyRangeQuery('height', '<', tall)
])
} else {
return cts.jsonPropertyRangeQuery('height', '>=', tall)
}
};
var reference = { height: refCallback };
jsearch.documents(
jsearch.facet('height').groupInto([
jsearch.bucketName('short'), short,
jsearch.bucketName('normal'), normal,
jsearch.bucketName('tall'), tall
]))
.where(cts.parse('height:tall', reference))
.result();
请注意,我还必须将变量声明外部化,因为现在我可以重用存储桶定义中的那些以及回调函数。