MarkLogic Node.js Sort on “last-modified”

拟墨画扇 提交于 2019-12-14 03:55:08

问题


I want to sort the documents by metadata property "last-modified". I have already created element-range-index on "last-modified" and also enabled option "maintain last modified" in Admin Panel for the database.But, when I run below statement in Node.js

return db.documents.query(
        qb.where().orderBy(qb.sort("last-modified")).slice(from, length)).result();

I am getting below error. Please help?

 Error { [Error: query documents: response with invalid 400 status]
  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 supp
ort element, element-attribute, json-property, or field sort specifications.' }
} }

回答1:


Update: clarified fragments explanation; fixed examples

The last-modified property (controlled by the maintain last modified setting) is not stored in the document itself, but in the document properties, which is a metadata fragment associated with each document. In the MarkLogic Node.js API, you can constrain queries to the document or the document properties with qb.documentFragment() or qb.propertiesFragment().

However, you can only sort by aspects of the data you are returning: by default, the document itself. You can specify that your query return either documents or properties using qb.fragmentScope().

Note: Document properties are stored as XML in the http://marklogic.com/xdmp/property namespace, so your element-range-index must also use that namespace.

Here's how you would get the 10 most-recent document properties:

return db.documents.query(
  qb.where(
    qb.fragmentScope('properties')
  ).orderBy(
    qb.sort(
      qb.element(qb.qname('http://marklogic.com/xdmp/property', 'last-modified')),
      'descending'
    )
  ).slice(1, 10))
.result();

You could further restrict these results by any query matching the document itself with qb.documentFragment():

assuming an int range index on test:

return db.documents.query(
  qb.where(
    qb.fragmentScope('properties'),
    qb.documentFragment(
      qb.range( qb.element('test'), '<', 20 )
    )
  ).orderBy(
    qb.sort(
      qb.element(qb.qname('http://marklogic.com/xdmp/property', 'last-modified')),
      'descending'
    )
  ).slice(1, 10))
.result();

Finally, if you want to then get the documents themselves, and not their properties, you could make a request to db.documents.read(), with the document URIs retrieved by the query:

Note: the following examples use lodash/underscore

return db.documents.query(
  qb.where(
    qb.fragmentScope('properties'),
    qb.documentFragment(
      qb.range( qb.element('test'), '<', 20 )
    )
  ).orderBy(
    qb.sort(
      qb.element(qb.qname('http://marklogic.com/xdmp/property', 'last-modified')),
      'descending'
    )
  ).slice(1, 10))
.result(function(documents) {
  db.documents.read(
    _.map(documents, 'uri')
  ).result(function(documents) {
    _.each(documents, function(doc) { console.log(doc.content); })
  });
});

Alternately, your application could maintain a last-modified property directly in your documents, in which case your query can be much simpler:

return db.documents.query(
  qb.where(
    qb.range( qb.element('test'), '<', 20 )
  ).orderBy(
    qb.sort( qb.element('last-modified'), 'descending' )
  ).slice(1, 10))
.result(function(documents) {
  _.each(documents, function(doc) { console.log(doc.content); })
});


来源:https://stackoverflow.com/questions/30091370/marklogic-node-js-sort-on-last-modified

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!