3
votes

I would like to take the last n documents from my Cloudant database using a Node query. So far I have narrowed it down to the find() function, but the documentation only really explains how to retrieve all documents containing an absolute value, for example:

db.find({selector:{name:'Alice'}}, function(er, result) {
    ...
});

(taken from https://www.npmjs.com/package/cloudant#cloudant-query)

What I'm looking for is the equivalent of this SQL:

SELECT * FROM db WHERE name = "Alice" LIMIT 10

The code I have so far is this:

var cloudant = require('cloudant');
cloudant({account: username, password: password}, function (err, conn) {
    if (err) {
        callback("Could not initialize connection to Cloudant: " + err);
    } else {
        var db = conn.db.use('mydb');
        db.find(???, function(err, data) {
            if (err) {
                callback("No data found: " + err);
            } else {
                ...
            }
        });
    }
});

If I need to make design documents, I'd do so in the Cloudant online interface, so don't worry too much about making an executable answer for that if it's necessary.

2

2 Answers

4
votes

It's important to note that Cloudant Query requires you to define your index before performing the query e.g. to index the 'name' field from your documents:

db.index( {name:'nameindex', type:'json', index:{fields:['name']}}

We can now query the data using the find function as you indicated:

var query = { selector: { name: 'Alice' }};
db.find(query, function(err, data) {
});

The interesting thing about your question is the phrase 'the last n documents'. We can retrieve 'n' documents by adding a 'limit' to our query.

var query = { selector: { name: 'Alice' }, limit: 10};
db.find(query, function(err, data) {
});

but this doesn't necessarily indicate the last ten documents; it just limits the result set to ten.

If you want your query results to appear in time order, then you'll need something in your documents that indicates the time e.g.

  • a time string : { "name": "Alice", "datetime": "2015-11-26 10:22:24 Z" }
  • a timestamp : { "name": "Alice", "ts": "123456678" }

When your document contains a field which represents time, then your index can be created incorporate this into the index e.g.

db.index( {name:'nameindex', type:'json', index:{fields:['name','time']}}

and documents can be queried to appear in *reverse order * (to get the latest first):

var query = { selector: { name: 'Alice' }, sort: [ { name: "desc"}, { ts: "desc"]};
db.find(query, function(err, data) {
});

You may also want to look at type:"text" indexes too. See https://docs.cloudant.com/cloudant_query.html

1
votes
var query = { selector: { name: 'Alice' }, sort: [ { name: "desc"}, { ts: "desc"]};

should be

var query = { selector: { name: 'Alice' }, sort: [ { name: "desc"}, { ts: "desc"}];