将XQuery Search API存储桶生成转换为MarkLogic中的JSearch

时间:2016-03-08 21:39:45

标签: javascript xquery marklogic

我想将一个使用存储桶(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()约束时,我的生成桶很好。有什么建议吗?

1 个答案:

答案 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();

请注意,我还必须将变量声明外部化,因为现在我可以重用存储桶定义中的那些以及回调函数。