How can I query pouchdb for deleted documents?
Asked Answered
P

3

7

I would like to list currently deleted documents in order to provide the ability to undelete one or more.

How can I query couchdb for deleted documents? I am actually using pouchdb.

Although this POST nicely describes how to query for and undelete a document, it requires an id of an existing doc.

I am looking for a way to query for all documents that have been deleted. The POST cites making a query for all changes. That query returns all documents that have been deleted IN ADDITION to any that have been edited/changed.

I am looking only for documents that have been deleted. Think querying for documents in the 'trash bin'. :)

Poisonous answered 11/8, 2017 at 17:44 Comment(2)
Possible duplicate of Retrieve just deleted documentGuttery
At this point I am thinking to add a deleted_at datetime value to each document. Using this I can emulate Laravel soft delete functionality. All my general queries would exclude docs with deleted_at value. That is unless there is a more elegant way to achieve this natively.Poisonous
P
8

Starting from couch 2.1.0, you can add various selectors to _changes feed. So your request to output only deleted documents will be:

curl -X POST -H "content-Type: application/json" "http://adm:[email protected]:15984/tracks/_changes?filter=_selector" -d '{"selector": {"_deleted": true}}'

Phrase answered 17/8, 2017 at 16:59 Comment(0)
D
4

You can add a filter to the _changes feed in PouchDB: https://pouchdb.com/api.html#filtered-changes

var changes = db.changes({
  filter: function(doc) {
    return doc._deleted;
  }
}).on('change', function(change) {
  console.log(change.id);
})
Dionysius answered 18/8, 2017 at 17:45 Comment(0)
A
1

For an all-in-one solution combining the open_revs tip from this answer, here's the TypeScript code I came up with:

const db = new PouchDB('my-db');

async function deletedDocIds(): Promise<string[]> {
  const ret: string[] = [];
  return new Promise((resolve, reject) => {
    db.changes({filter: d => d._deleted})
        .on('change', c => ret.push(c.id))
        .on('complete', () => resolve(ret))
        .on('error', e => reject(e));
  });
}

async function deletedDocs() {
  const ids = await deletedDocIds();
  return Promise.all(ids.map(id => db.get(id, {revs: true, open_revs: 'all'}).then(x => {
    const revs = (x[0].ok as any)._revisions;
    const lastRev = (revs.start - 1) + '-' + revs.ids[1];
    return db.get(id, {rev: lastRev}); // with Pouchdb keys too
  })));
}

Calling deletedDocs() will return a promise of an array of all deleted docs as per the rev just prior to deletion.

N.B., the elements of the array will include PouchDb metadata as well as your document's keys.

N.B. 2, version 6.1.3 of DefinitelyTyped's TypeScript bindings for pouchdb-browser which I'm using here (should work for @types/pouchdb too though) doesn't seem to know about the _revisions key, hence the as any escape hatch.

N.B. 3, this should be trivial to manually translate to plain JS, just delete the type declarations and coercions (:, as, and whatever token follows these).

Arginine answered 21/8, 2020 at 4:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.