使用 StructuredQueryBuilder 指定动态排序顺序
Specify dynamic sort order with StructuredQueryBuilder
在 Java 客户端 API 中使用 MarkLogic 7 时,我目前正在将我的查询定义从 StringQueryDefinition
移动到 StructuredQueryDefinition
允许我以编程方式构造和操作查询。
通过字符串查询,我能够成功地将排序运算符与 sort:{my-sort-order}
结合使用,后者又引用查询选项 (https://docs.marklogic.com/guide/search-dev/query-options#id_30002) 中指定的预定义订单的名称,但找不到API 记录了一个相关方法,允许我使用结构化查询生成器指定排序顺序。
关于如何在使用 StructuredQueryDefinition
时指定排序顺序的推荐方法是什么?
更新
根据 Erik 的建议,这就是代码片段当前的样子,但它并没有解决问题,因为 operator-state
必须作为 query
元素的子元素而不是 query
元素的子元素search
元素:
RawStructuredQueryDefinition queryDef = qb.build(qb.and(qb.term(..), qb.rangeConstraint(...)));
String sorting = "<operator-state><operator-name>sort</operator-name><state-name>" + orderBy + "</state-name></operator-state>";
String combi = "<search xmlns='http://marklogic.com/appservices/search'>" + queryDef.toString() + sorting + "</search>";
RawCombinedQueryDefinition combinedQueryDef = queryManager.newRawCombinedQueryDefinition(new StringHandle(combi), OPTIONS);
// DOES NOT WORK, but will lead to MarkLogicIOException "Could not construct search results: parser error"
// Possible solution is to modify the queryDef DOM your own
排序顺序被认为是一个运算符。查看 operator-state,您将找到一个在结构化查询中进行排序的示例。
目前,StructuredQueryBuilder 仅构建条件。您将不得不参考带有排序顺序的持久查询选项,或者发送包含条件和选项的组合搜索。
我们正在跟踪这个 on GitHub。请随时在此处添加信息。
这是我最终得到的解决方案,基本上我使用编程方式使用 StructuredQueryBuilder
构建查询,然后注入 operator-state
,指的是我的预定义排序顺序选项(OPTIONS_ALL
):
org.jdom2.Document doc = new SAXBuilder().build(new StringReader(queryDef.serialize()));
if (!StringUtils.isEmpty(orderBy)) {
Element operatorState = new Element("operator-state", NAMESPACE_SEARCH);
operatorState.addContent(new Element("operator-name", NAMESPACE_SEARCH).setText("sort"));
operatorState.addContent(new Element("state-name", NAMESPACE_SEARCH).setText(orderBy));
doc.getRootElement().addContent(operatorState);
}
RawStructuredQueryDefinition rawQueryDef =
queryManager.newRawStructuredQueryDefinition(new JDOMHandle(doc), OPTIONS_ALL);
// ~~
SearchHandle resultsHandle = new SearchHandle();
queryManager.search(rawQueryDef, resultsHandle, start);
有
public static final Namespace NAMESPACE_SEARCH = Namespace.getNamespace("http://marklogic.com/appservices/search");
我们使用了发送到服务器的 <search>
元素的 <options>
标签。
这需要一个丑陋的字符串连接,但它不需要服务器端的任何东西,除了排序 属性.
上的索引
有关 XML 的格式,请参阅此 link 或 search.xsd:
http://docs.marklogic.com/guide/rest-dev/appendixb#id_33716
我们的想法是生成一个像这样的 XML :
<search xmlns='http://marklogic.com/appservices/search'>
<query xmlns="http://marklogic.com/appservices/search">
<collection-query>
<uri>a_collection</uri>
</collection-query>
</query>
<options>
<sort-order type="xs:dateTime" direction="descending">
<json-property>a_field</json-property>
</sort-order>
</options>
</search>
我们是这样做的:
首先,构建您的 StructuredQueryDefinition
StructuredQueryDefinition queryDef = sb.collection("my_collection);
构建上面看到的 <options>
元素
String xmlSortNode =
" <options>" +
" <sort-order type=\"xs:dateTime\" direction=\"descending\">" +
" <json-property>a_field</json-property>" +
" </sort-order>" +
" </options>";
构建完整的 search
元素
String searchXml="<search xmlns='http://marklogic.com/appservices/search'>"
+ queryDef.serialize()
+ xmlSortNode
+ "</search>";
执行查询
queryManager.newRawCombinedQueryDefinition(new StringHandle(searchXml),"all");
在 Java 客户端 API 中使用 MarkLogic 7 时,我目前正在将我的查询定义从 StringQueryDefinition
移动到 StructuredQueryDefinition
允许我以编程方式构造和操作查询。
通过字符串查询,我能够成功地将排序运算符与 sort:{my-sort-order}
结合使用,后者又引用查询选项 (https://docs.marklogic.com/guide/search-dev/query-options#id_30002) 中指定的预定义订单的名称,但找不到API 记录了一个相关方法,允许我使用结构化查询生成器指定排序顺序。
关于如何在使用 StructuredQueryDefinition
时指定排序顺序的推荐方法是什么?
更新
根据 Erik 的建议,这就是代码片段当前的样子,但它并没有解决问题,因为 operator-state
必须作为 query
元素的子元素而不是 query
元素的子元素search
元素:
RawStructuredQueryDefinition queryDef = qb.build(qb.and(qb.term(..), qb.rangeConstraint(...)));
String sorting = "<operator-state><operator-name>sort</operator-name><state-name>" + orderBy + "</state-name></operator-state>";
String combi = "<search xmlns='http://marklogic.com/appservices/search'>" + queryDef.toString() + sorting + "</search>";
RawCombinedQueryDefinition combinedQueryDef = queryManager.newRawCombinedQueryDefinition(new StringHandle(combi), OPTIONS);
// DOES NOT WORK, but will lead to MarkLogicIOException "Could not construct search results: parser error"
// Possible solution is to modify the queryDef DOM your own
排序顺序被认为是一个运算符。查看 operator-state,您将找到一个在结构化查询中进行排序的示例。
目前,StructuredQueryBuilder 仅构建条件。您将不得不参考带有排序顺序的持久查询选项,或者发送包含条件和选项的组合搜索。
我们正在跟踪这个 on GitHub。请随时在此处添加信息。
这是我最终得到的解决方案,基本上我使用编程方式使用 StructuredQueryBuilder
构建查询,然后注入 operator-state
,指的是我的预定义排序顺序选项(OPTIONS_ALL
):
org.jdom2.Document doc = new SAXBuilder().build(new StringReader(queryDef.serialize()));
if (!StringUtils.isEmpty(orderBy)) {
Element operatorState = new Element("operator-state", NAMESPACE_SEARCH);
operatorState.addContent(new Element("operator-name", NAMESPACE_SEARCH).setText("sort"));
operatorState.addContent(new Element("state-name", NAMESPACE_SEARCH).setText(orderBy));
doc.getRootElement().addContent(operatorState);
}
RawStructuredQueryDefinition rawQueryDef =
queryManager.newRawStructuredQueryDefinition(new JDOMHandle(doc), OPTIONS_ALL);
// ~~
SearchHandle resultsHandle = new SearchHandle();
queryManager.search(rawQueryDef, resultsHandle, start);
有
public static final Namespace NAMESPACE_SEARCH = Namespace.getNamespace("http://marklogic.com/appservices/search");
我们使用了发送到服务器的 <search>
元素的 <options>
标签。
这需要一个丑陋的字符串连接,但它不需要服务器端的任何东西,除了排序 属性.
有关 XML 的格式,请参阅此 link 或 search.xsd: http://docs.marklogic.com/guide/rest-dev/appendixb#id_33716
我们的想法是生成一个像这样的 XML :
<search xmlns='http://marklogic.com/appservices/search'>
<query xmlns="http://marklogic.com/appservices/search">
<collection-query>
<uri>a_collection</uri>
</collection-query>
</query>
<options>
<sort-order type="xs:dateTime" direction="descending">
<json-property>a_field</json-property>
</sort-order>
</options>
</search>
我们是这样做的:
首先,构建您的 StructuredQueryDefinition
StructuredQueryDefinition queryDef = sb.collection("my_collection);
构建上面看到的
<options>
元素String xmlSortNode = " <options>" + " <sort-order type=\"xs:dateTime\" direction=\"descending\">" + " <json-property>a_field</json-property>" + " </sort-order>" + " </options>";
构建完整的
search
元素String searchXml="<search xmlns='http://marklogic.com/appservices/search'>" + queryDef.serialize() + xmlSortNode + "</search>";
执行查询
queryManager.newRawCombinedQueryDefinition(new StringHandle(searchXml),"all");