Subdoc on non existing document?


#1

Hi!

I am trying to figure out is there a way to auto create document if it is not exists yet and update some of it’s properties? Or should I upsert first and then mutate?

Thnks!

ps
Nodejs sdk 2.5 and Server 5.0.1


#2

Hey @Cyb,

If you would be able to explain the exact semantics you’re looking for a little bit better, I can probably give you more specific guidance. However, the insert operation or the mutateIn operation coupled with createDoc (and createPath) are probably what you are looking for.

Cheers, Brett


#3

Hi, @brett19

I need to mutate some doc fields but this doc may not exists yet. For now I am using basic scenario:

  1. mutate fields (if doc exists then everything ok)
  2. if mutate failed then insert new doc with those fields

Hoped that there is a better way to do it in 1 round trip…

ps:
here Sub-doc API - upsert auto-create document? some mention of make_doc flag but I could not find it in nodejs docs or sources :slight_smile:


#4

Hey @Cyb,

You should be able to do this using something like the following:

bucket.mutateIn('mydoc', {upsert: true})
  .upsert('foo.bar', 10, {createParents: true})
  .upsert('foo.baz', 20, {createParents: true})
  .execute((err) => {
    // Completed!
  });

P.S. I’ve opened an issue related to the missing documentation for the upsert and insert options that the Node.js understands for a mutateIn operation:
https://github.com/couchbase/couchnode/blob/master/lib/bucket.js#L3613-L3618)
https://issues.couchbase.com/browse/JSCBC-529

Cheers, Brett


#5

Yes, that’s what I am looking for :slight_smile:

@brett19, thanks a lot!


#6

@brett19 can you explain difference of upsert and insert options for a mutateIn operation?

bucket.mutateIn('mydoc', {upsert: true})
  .upsert('foo.bar', 10, {createParents: true})
  .upsert('foo.baz', 20, {createParents: true})
  .execute((err) => {
    // Completed!
  });
bucket.mutateIn('mydoc', {insert: true})
  .upsert('foo.bar', 10, {createParents: true})
  .upsert('foo.baz', 20, {createParents: true})
  .execute((err) => {
    // Completed!
  });
bucket.mutateIn('mydoc', {upsert: true,insert: true})
  .upsert('foo.bar', 10, {createParents: true})
  .upsert('foo.baz', 20, {createParents: true})
  .execute((err) => {
    // Completed!
  });

#7

Hey @socketman2016,

The difference is in the behaviour with the underlying document. Upsert semantics mean that if the underlying document does not exist, a blank document will be created and then the subdocument operations performed against it. Insert semantics mean that the operations will only execute if the document does not exist. Replace semantics (the default) mean that the operations only execute if the document exists already.

Cheers, Brett


#8

Why we must use mutateIn with insert option?

What is the difference of the following codes

bucket.mutateIn('mydoc', {insert: true})
  .upsert('foo.bar', 10, {createParents: true})
  .upsert('foo.baz', 20, {createParents: true})
  .execute((err) => {
    // Completed!
  });
bucket.insert('mydoc', {
 foo:{
    bar:10,
    baz:20,
}
},(err) => {
    // Completed!
  });