问题
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