3

I am listening to the changes from all the databases on my CouchDB instance using nano in my node.js application to follow the _global_changes database.

const globalChanges = nano.use('_global_changes');
const feed = globalChanges.follow({ since: "now", include_docs: true });
feed.on('change', function (change) {
  // Here's the change that just happened
  console.log(change);
});
feed.follow();

This works great in returning a reference to every change as it occurs, but I am at a loss as to how I can access the actual document and the details of the change from this point.

Every change that comes out of the feed looks like this:

{ 
    seq: '84-g1AAAAJjeJyd0UsKwjAQBuDY-tq6EJd6AklS-3Blb6KZTIdSqq5c6030JnoTvUlN0m6EIrQEJjDh_2AyJWNsmvvIZvp80TlCKmS85uaI0jx5isGyqqoi99XiaBoTzYmQoC3wh4GVqbBrpLmTBIQoxaarlFpp30gjJyUipAi2XaWDla4_02WSVIyyo3Qamspu5jLY3WpjpwHXQkW8l_aotafVBk6jhHgg-2mvWntbzXMaZjFxxF7ap9bcv_n1BhJFKlBtueILoc2geA',
    id: 'updated:DATABASE-WHERE-CHANGE-HAPPENED',
    changes: [ { rev: '22-8a4f097580a344b3d70e5adc17971cb4' } ],
    doc: { 
        _id: 'updated:DATABASE-WHERE-CHANGE-HAPPENED',
        _rev: '22-8a4f097580a344b3d70e5adc17971cb4' 
    }
}

From this point, I can't figure out how I can query DATABASE-WHERE-CHANGE-HAPPENED to get the specific document that was changed/deleted/added, and find out exactly what happened to it. I can't find a document in DATABASE-WHERE-CHANGE_HAPPENED that matches change._rev or change.seq...

Any help would be greatly appreciated.

(I am trying to listen for whenever a certain type of attachment is added, and then do something with that attachment.)

MY SOLUTION

As Hypnic Jerk pointed out in the comment below, there doesn't seem to be any way for me to do this. Instead, whenever a change is made, the only information I get from the Global changes feed is that a change was made in a particular database. So then, I need to query the whole database in question to find if there's some piece of information I am interested in.

In my use case this was easy because I am looking for a certain type of file that might be added as an attachment, and then converting it to a different file type. But for other use cases this could be very difficult or impossible. It would be really helpful if CouchDB could show more information about the changes made in the global _global_changes feed.

const globalChanges = nano.use('_global_changes');
const feed = globalChanges.follow({ since: "now", include_docs: true });
feed.on('change', function (change) {
  // STEP 1 - See if the database mentioned in change.doc._id
  // is one that I am interested in
  // STEP 2 - If so, extract the database name from change.doc._id
  // STEP 3 - Query the database with this name for any docs
  // with attachments
  // const db = nano.use(databaseName);
  // const docsWithAttachments = await db.find({ 
  //    selector: { _attachments: { "$exists": true }}
  //    } ,{ include_docs: true });
  // STEP 4 - Go through all the attachments for each document to see if
  // there are any files of the type that I am interested in. 
  // STEP 5 - Do something with those files.
});
feed.follow();

So yes, this causes a lot of extra querying and it works OK for my use case, but for other use cases this may not be as feasible. Sadly, the only information that the _GLOBAL_CHANGES feed seems to give is to tell you which database was modified, unless I am missing something?

Adam D
  • 1,962
  • 2
  • 21
  • 37
  • Would you not use the `_id` to find the document? – Hypnic Jerk Dec 05 '18 at 20:49
  • The `_id` there is not the `_id` of the document. It's just contains `updated:` + the name of the database that was changed. (Sorry I forgot to blank out the second one, they are both the same in the object above). The only information I can get from the `_id` is the name of the database that was modified. – Adam D Dec 06 '18 at 04:45
  • Ah I see now. I misunderstood your post. Youre listening to ALL db changes, not specific ones. Sadly I have no experience with this and cant research atm. – Hypnic Jerk Dec 06 '18 at 04:47
  • 1
    After investigating and testing some on CouchDB v 2.2.0, I don't believe there is a way for you to do this. The only workaround would be to have a separate `changes` feed listening to every DB, and deal with those accordingly, which can be a lot depending on how many DBs you have and may slow down performance of your app. – Hypnic Jerk Dec 07 '18 at 16:35
  • Yes, I was coming to the same conclusion myself. I thought of taking the database modified from the global changes feed I was listening to, and then grabbing the changes feed from the database where changes happened, looking for the most recent change/document. Unfortunately this also was problematic because I am also updating the CouchDB instance via PouchDB, and it seems like they update bunches of documents at once. So in my case, I devised an incredibly long and complex way of doing what I wanted to do, and it works. :-) But it sure would be nice if CouchDB had this feature. – Adam D Dec 07 '18 at 18:53
  • @AdamD i am trying something similar - creating stats if a db changed and writing a stats doc back ... which in turn triggers global changes ... so I thought filtering the changed docs id for 'stats' could help .. but there are no doc ids provided in the feed ... how did you approach it in your case? – BananaAcid Jan 24 '20 at 09:50
  • 1
    @BananaAcid see my edit with my solution/pseudocode above. You are correct that there are no doc ids provided in the feed. On each global changes event I had to query the entire database in question to see if something showed up that I was looking for. – Adam D Jan 24 '20 at 15:06
  • @AdamD I used `nano.followUpdates({since: 'now, feed: 'continuous'});` [`/_db_changes`] - either way, no doc id to reference. Do you know, if `/dbname/_changes` contains any seq part that could be aligned with the seq from the global feed (as that feed contains doc ids)? – BananaAcid Jan 24 '20 at 16:25
  • @BananaAcid that's a good question and I don't know, sorry. If you find out that the `seq` from the results of `_global_changes` lines up with the `seq` attached to change logs in `/dbname/_changes` please let me know. – Adam D Jan 24 '20 at 23:32

0 Answers0