在 MarkLogic 中将 XQuery 搜索 API 存储桶生成转换为 JSearch
Convert XQuery Search API bucket generation to JSearch in MarkLogic
我想 "convert" 我的一个旧 XQuery 示例,它使用 bucket(分桶搜索)到 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();
以上代码returns:
{
"results":空,
"estimate": 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()
约束时,我的存储桶生成得很好。有什么建议吗?
我相信我已经找到了解决办法。高度的值是数字,在我的 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();
请注意,我还必须外部化变量声明,因为现在我可以在存储桶定义和回调函数中重用它们。
我想 "convert" 我的一个旧 XQuery 示例,它使用 bucket(分桶搜索)到 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();
以上代码returns:
{ "results":空, "estimate": 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()
约束时,我的存储桶生成得很好。有什么建议吗?
我相信我已经找到了解决办法。高度的值是数字,在我的 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();
请注意,我还必须外部化变量声明,因为现在我可以在存储桶定义和回调函数中重用它们。