i want to perform a replacement and not an update to apply a document insertion, in case the document do not exists.
What you're looking for is "upsert" (or "replsert" if we can name it like this in RethinkDB), and as far as I know, there is no such an operation in RethinkDB. .replace()
requires at least a document to be found therefore it cannot do insert. However, it can be easily implemented and can be flavored with ReQL spices as well.
The example below can be tested directly in Data Explorer:
const OLD_DOCUMENT = { id: 'xxx', title: 'my title', description: 'my desc', createdAt: '1507844981006' };
const NEW_DOCUMENT = { id: 'xxx', title: 'my title2', description: 'my desc2' };
r.db('TEST')
.table('TEST')
.delete();
// Comment out the following query to test the .insert() scenario,
// or uncomment it to test the .replace() scenario
r.db('TEST')
.table('TEST')
.insert(OLD_DOCUMENT);
r.db('TEST')
.table('TEST')
.replace((doc) => r.expr(NEW_DOCUMENT).merge(doc.pluck('createdAt')))
.do(replaceData => r.branch(
// Did the .replace() operation succeed with a real replacement?
replaceData.getField('replaced').gt(0),
// Then just return the replace result
replaceData,
// Otherwise, perform an insert
r.db('TEST')
.table('TEST')
.insert(
// Bonus (not just .insert(NEW_DOCUMENT))
r.branch(
// Does the document have the createdAt property set?
r.expr(NEW_DOCUMENT).hasFields('createdAt'),
// If yes, then no transformation is required
NEW_DOCUMENT,
// Else add the timestamp in your format
r.expr(NEW_DOCUMENT).merge({ createdAt: r.now().toEpochTime().mul(1000).coerceTo('string') })
)
)
));
r.db('TEST')
.table('TEST');
.insert()
scenario results
{
"createdAt": "1507890036302", // this property value will grow in time
"description": "my desc2",
"id": "xxx",
"title": "my title2"
}
.replace()
scenario results
{
"createdAt": "1507844981006", // this value never changes in your test
"description": "my desc2",
"id": "xxx",
"title": "my title2"
}
A matter of style and preferences, the following expressions can be reused:
const TABLE_EXPR = r.db('TEST').table('TEST');
const NEW_DOCUMENT_EXPR = r.expr(NEW_DOCUMENT);