尝试在dateTime索引上对MarkLogic集合查询结果进行排序

时间:2015-10-26 20:03:07

标签: node.js sorting marklogic

我正在使用node.js来设置应用程序。我正在使用节点来测试一些东西。我使用node.js中的marklogic模块来查询数据库并返回JSON。为此我写了一个关于XML内容的转换,它可以工作。

现在我想在数据的时间戳上订购集合查询的结果。时间戳的索引类型为xs:dateTime。并且生活在一个名称空间中,并且#34; http://exmaple.com/sccs"。

示例文件:

<?xml version="1.0"?>
<obj:object xmlns:obj="http://marklogic.com/solutions/obi/object">
  <obi:metadata xmlns:obi="http://marklogic.com/solutions/obi" createdBy="user-app-user" createdDateTime="2015-10-26T16:42:30.302458Z" lastUpdatedBy="user-app-user" lastUpdatedDateTime="2015-10-26T16:45:01.621435Z">
</obi:metadata>
  <obj:label>This alert was send based on the First Time Seen RuleThis subject was spotted first time at this sensor location</obj:label>
  <obj:type>alert</obj:type>
  <obj:id>c2151ee0-f0a9-4eb5-85c2-1c5b3c7c7a65</obj:id>
  <obj:content>
    <alert xmlns="http://example.com/sccs/alert">
      <obj:property sourceCount="1">
        <actions type="array" elementType="string">
          <action>This alert was send based on the First Time Seen Rule</action>
          <action>This subject was spotted first time at this sensor location</action>
        </actions>
      </obj:property>
      <obj:property sourceCount="1">
        <status>Inactive</status>
      </obj:property>
      <obj:property sourceCount="1">
        <sensor-id>test-sensor-id</sensor-id>
      </obj:property>
      <obj:property sourceCount="1">
        <device-id>00:00:00:00:00:04</device-id>
      </obj:property>
      <obj:property sourceCount="1">
        <alertType>trespasser-alert</alertType>
      </obj:property>
      <obj:property sourceCount="1">
        <position>{"type":"Point", "coordinates":[52.2, 4.3]}</position>
      </obj:property>
      <obj:property sourceCount="1">
        <scc:id xmlns:scc="http://example.com/sccs">04fdef0a-9d3f-4743-9e88-04da279a0c37</scc:id>
      </obj:property>
      <obj:property sourceCount="1">
        <scc:timestamp xmlns:scc="http://example.com/sccs">2015-10-01T13:06:00Z</scc:timestamp>
      </obj:property>
    </alert>
  </obj:content>
  <obj:workspaces>
    <obj:workspace id="Public">
</obj:workspace>
  </obj:workspaces>
  <obj:sourceIds count="1">
    <source:id xmlns:source="http://marklogic.com/solutions/obi/source">57358890-8d71-4515-90c1-5cacc54347f7</source:id>
  </obj:sourceIds>
</obj:object>

现在我的节点脚本:

var marklogic = require('marklogic');
var my = require('./my-connection.js');

var db = marklogic.createDatabaseClient(my.connInfo);
var qb = marklogic.queryBuilder;

var options = {
    "sort-order": [
      {
        "direction": "descending",
        "type": "xs:dateTime",
        "collation": "http://marklogic.com/collation/codepoint",
        "element": {
          "name": "timestamp",
          "ns": "http://sensingclues.com/sccs",
        },
        "annotation": [ "some user comment can go here" ] },
      {
        "direction": "ascending",
        "score": null
      }
    ]
  };

db.documents.query(
  qb.where(
    qb.collection("alert")
    ).orderBy(qb.sort('timestamp'))//.withOptions(options)//.orderBy(qb.sort('timestamp'))
    //.slice(qb.transform('alerts-query-transform')) // HK :use transform
).result( function(documents) {
    var arrAlerts = new Array();

    console.log('The alerts collection:')

    documents.forEach( function(document) {

      arrAlerts.push(document.content);

    });
    console.log(arrAlerts);

}, function(error) {
    console.log(JSON.stringify(error, null, 2));
});

给出:

node alerts-no-transform-test.js 
{
  "message": "query documents: response with invalid 400 status",
  "statusCode": 400,
  "body": {
    "errorResponse": {
      "statusCode": 400,
      "status": "Bad Request",
      "messageCode": "SEARCH-BADORDERBY",
      "message": "SEARCH-BADORDERBY: (err:FOER0000) Indexes are required to support element, element-attribute, json-property, or field sort specifications."
    }
  }
}

如果我尝试使用上面定义的选项,我会得到:

node alerts-no-transform-test.js 
/home/hugo/git/sccss-middletier/cluey-app/node_modules/marklogic/lib/query-builder.js:4807
        throw new Error('unknown option '+key);
              ^
Error: unknown option sort-order
    at QueryBuilder.withOptions (/home/hugo/git/sccss-middletier/cluey-app/node_modules/marklogic/lib/query-builder.js:4807:15)
    at Object.<anonymous> (/home/hugo/git/sccss-middletier/cluey-app/alerts-no-transform-test.js:33:6)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

问题:根据时间戳dateTime索引对结果进行排序的正确方法是什么?

2 个答案:

答案 0 :(得分:4)

您在示例排序顺序配置中提到了此排序规则:

  

“整理”:“http://marklogic.com/collation/codepoint”,

但是,您在索引配置中提到了特定排序规则。 然而在MarkLogic 8中,默认排序规则不是代码点,而是UCA Root Collation

您可能只是尝试对不存在的索引进行排序(因为索引是使用默认排序规则创建的,而您的代码是使用代码点排序规则)。

我怀疑这是因为消息:

  "message": "SEARCH-BADORDERBY: (err:FOER0000) Indexes are required to support element, element-attribute, json-property, or field sort specifications."

在这样的情况下,我总是在queryConsole中使用cts:element-values()cts:values()等来测试我的索引并确保它完全符合我的预期 - 在我尝试在代码中引用它之前。这可以帮助您确保索引符合您的预期。

答案 1 :(得分:0)

好的我在SO here

上找到了一个指针

现在可行:

// get all the devices from ML
db.documents.query(
  qb.where(
    qb.collection("alert")
    ).orderBy(qb.sort(qb.element(qb.qname('http://example.com/sccs', 'timestamp')),
  'descending'))
    .slice(qb.transform('alerts-query-transform')) // HK: use transform
).result( function(documents) {

显然我必须明确指向元素?是否有关于如何详细使用查询构建器的有用文档?

侧面:注意应用于XML的转换以映射到JSON ...