RethinkDB: Upsert Example

To create a test case, we’ll make a table:

r.db('test').table('users').insert([{
  first_name: 'gary',
  last_name: 'sieling'
},
{
  first_name: 'melissa'
},
{
  last_name: 'a test'
}])
id
first_name
last_name
1
46454a3e-ba9e-4991-bc7f-53f1e5c19906
gary
sieling
2
450e77d6-d5c6-4533-b2d7-c0158bb097c9
melissa
undefined
3
e08b00c8-b8d2-465b-9886-ee014d14e751
undefined
a test

If you try to re-insert these, you’ll get a duplicate key violation:

r.db('test')
 .table('users')
 .insert({
  id: '46454a3e-ba9e-4991-bc7f-53f1e5c19906',
  first_name: 'test upsert 1',
  last_name: 'test upsert 2'
})
Duplicate primary key `id`:
{
  "first_name":	"gary",
  "id":	"46454a3e-ba9e-4991-bc7f-53f1e5c19906",
  "last_name":	"sieling"
}
{
  "first_name":	"test upsert 1",
  "id":	"46454a3e-ba9e-4991-bc7f-53f1e5c19906",
  "last_name":	"test upsert 2"
}

If you want to do an upsert, you can choose to either replace the entire object, or just matching keys.

To replace the entire object:

r.db('test').table('users').insert({
  id: '46454a3e-ba9e-4991-bc7f-53f1e5c19906',
  first_name: 'test upsert 1',
  last_name: 'test upsert 2'
}, {
  conflict: 'replace'
})

If you want to merge objects, you can do it with ‘update’:

r.db('test').table('users').insert({
  id: '46454a3e-ba9e-4991-bc7f-53f1e5c19906',
  first_name: 'Gary'
}, {
  conflict: 'update'
})

You can also use this to add new attributes to existing objects.

Note that you can’t replace pieces of the object this way, as they will get replaced in their entirety:

r.db('test').table('users').insert({
  id: '46454a3e-ba9e-4991-bc7f-53f1e5c19906',
  work_history: [
    {title: 'Job 1'},
    {title: 'Job 2'}
  ]  
}, {
  conflict: 'update'
});

r.db('test').table('users').insert({
  id: '46454a3e-ba9e-4991-bc7f-53f1e5c19906',
  work_history: [
    {employer: 'Employer 1'},
    {title: 'Employer 2'}
  ]  
}, {
  conflict: 'update'
})