有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用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元素的子元素,而不是作为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

共 (5) 个答案

  1. # 1 楼答案

    我们使用了发送到服务器的<search>元素的<options>标记。 这需要一个难看的字符串连接,但除了sort属性上的索引之外,它不需要任何服务器端的东西

    有关XML的格式,请参阅此链接或搜索。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>
    

    我们是这样做的:

    1. 首先,构建StructuredQueryDefinition

      StructuredQueryDefinition queryDef = sb.collection("my_collection);
      
    2. 构建上面看到的<options>元素

      String xmlSortNode =
              "  <options>" +
              "    <sort-order type=\"xs:dateTime\" direction=\"descending\">" +
              "      <json-property>a_field</json-property>" +
              "    </sort-order>" +
              "  </options>";
      
    3. 构建完整的search元素

      String searchXml="<search xmlns='http://marklogic.com/appservices/search'>"
        + queryDef.serialize()
        + xmlSortNode
        + "</search>";
      
    4. 执行查询

      queryManager.newRawCombinedQueryDefinition(new StringHandle(searchXml),"all");
      
  2. # 2 楼答案

    目前,StructuredQueryBuilder只生成标准。您必须使用排序顺序引用持久化查询选项,或者发送带有条件和选项的组合搜索

  3. # 3 楼答案

    这就是我最终得到的解决方案,基本上我使用编程的方式用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");
    
  4. # 4 楼答案

    排序顺序被认为是一个运算符。看看operator-state,您会发现一个结构化查询中排序的示例

  5. # 5 楼答案

    我们正在跟踪这个on GitHub。请随时在那里添加信息