【问题标题】:Partial document read and pagination by property in MarklogicMarklogic中按属性读取部分文档和分页
【发布时间】:2017-10-17 23:35:00
【问题描述】:

我正在研究使用 Marklogic 的医疗系统。前段时间我问了一个问题 (How to query a graph of documents of different types at once in Marklogic?),这导致我们决定使用一个包含大部分患者信息的大型患者文档。出于示例的目的,我将展示一个简化的 Patient 文档,其中包含 Appointments 数组。

简化的患者文档

{
    "firstName": "Chauncey", 
    "lastName": "Hays", 
    "memberId": "KLKB XMQ 77", 
    "dateOfBirth": "1971-09-11", 
    "gender": "MALE", 


    "appointments": [
        { 
            "name": "Follow Up", 
            "start": "2017-06-08T23:13:00Z", 
            "end": "2017-06-09T00:43:00Z" 
        },
        {
            "name": "Follow Up", 
            "start": "2017-06-09T23:13:00Z", 
            "end": "2017-06-10T00:43:00Z" 
        }
    ]

}

我们的一个用例是返回按患者数据过滤的分页约会(患者文档的属性),例如查找所有男性患者的约会页面。我们已经为此苦苦挣扎了一段时间,但没有运气。我看到的一个解决方案(可能稍微过度设计)是返回一个患者页面(患者页面可能导致比页面大小更多的约会)并在服务器端过滤掉约会。

我的主要问题是:在 Marklogic 中按患者数据(性别 = MALE)过滤、部分读取(读取约会)和按约会(患者文档的属性)对结果进行分页是否可行? 任何 cmets 都非常感谢。

【问题讨论】:

    标签: graph pagination marklogic marklogic-8 nosql


    【解决方案1】:

    您是对的,对于您的用例结构化查询选项“searchable-expression”将不起作用,因为您的查询过滤器位于可搜索表达式之外。不过,这是我尝试的匹配 0 个结果的方法:

    String query = "{ \"search\": {" +
      "\"query\": {" +
      "  \"value-query\": {" +
      "    \"json-property\": \"gender\"," +
      "    \"text\": \"MALE\"" +
      "  }" +
      "}," +
      "\"options\": {" +
      "  \"searchable-expression\": {" +
      "    \"text\": \"appointments\"" +
      "  }" +
      "}}}";
    QueryManager queryMgr = client.newQueryManager();
    RawCombinedQueryDefinition queryDef =
      queryMgr.newRawCombinedQueryDefinitionAs(Format.JSON, query);
    queryMgr.search(queryDef, new SearchHandle());
    

    虽然extract-document-data 有效,但就像您所描述的那样,您实际上是在对文档进行分页,而不是提取的部分。尽管如此,这是我尝试正确匹配并返回所需结果的方法,但没有提供按需要分页的方法:

    String query = "{ \"search\": {" +
      "\"query\": {" +
      "  \"value-query\": {" +
      "    \"json-property\": \"gender\"," +
      "    \"text\": [\"MALE\"]" +
      "  }" +
      "}," +
      "\"options\": {" +
      "  \"extract-document-data\": {" +
      "    \"extract-path\": \"/appointments\"" +
      "  }" +
      "}}}";
    QueryManager queryMgr = client.newQueryManager();
    RawCombinedQueryDefinition queryDef =
      queryMgr.newRawCombinedQueryDefinitionAs(Format.JSON, query);
    DocumentManager docMgr = client.newDocumentManager();
    DocumentPage page = docMgr.search(queryDef, 1);
    

    所以我认为您需要使用服务器端脚本,最好是resource extension 的形式。或者你可以做一个invoke。在模块数据库中将此脚本安装为“/ext/pageAppointments.xqy”:

      declare variable $start as xs:long external;
      declare variable $pageLength as xs:long external;
      let $appointments :=
        cts:search(collection(), cts:json-property-value-query("gender", "MALE"))/appointments
      return $appointments[$start to ($start + $pageLength - 1)]
    

    然后在 Java 中运行它:

    ServerEvaluationCall call = client.newServerEval()
      .modulePath("/ext/pageAppointments.xqy")
      .addVariable("start", 1)
      .addVariable("pageLength", 10);
    EvalResultIterator results = call.eval();
    try {
      for ( EvalResult result : results ) {
        JsonNode appointment = result.getAs(JsonNode.class);
        System.out.println(appointment);
      }
    } finally { results.close(); }
    

    【讨论】:

    • 谢谢。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-09
    相关资源
    最近更新 更多