Idempotent document creation (i.e. ignoring unique constraint violation)

Hi there,

This seems like a simple-enough use case, but I haven’t found any solution in the forums or elsewhere on the web:

I am working on a system (on the JVM) that needs to create documents idempotently, meaning that, when attempting to create a document with an ID that already exists, then nothing should happen.

I currently use a unique index for the ID, so I get this exception when trying to create a document with a pre-existing ID:

BadRequestException: instance not unique: document is not unique.

Now I could either catch the exception and ignore it based on its message (but that’s a hack, and it won’t work if bulk-creating documents), or I could query the index first and only create those documents which don’t yet exist (but that’s both verbose and inefficient, because the index will presumably be checked again upon document creation).

I’m sure I’m not the first to deal with such a case :-). What’s the best practice here?

Cheers,

Felix

If(Exists($match or $ref), Create(), ...) should do the trick. You just need to decide what you want to do in the else case.

1 Like

Hi Ben, thanks a lot for your response. I was hoping that there might be a more efficient solution, since - I presume - this one will make the same query on the unique index twice (once in Exists and once in Create ).

If you want to do common sub expression elimination you can do Let({ref: $ref-expr}, If(Not(Exists(Var("ref"))), Create(Var("ref"), ...), ...)) will only cost one read. But even if you don’t do that we cache reads locally during query eval so it’s still one read-op.

1 Like

we cache reads locally during query eval so it’s still one read-op

That’s great, good to know!

So I’m going for:

If(Exists(Match(Index("unique_id"), "id")), false, Create(...))

(Note that the Create() needs to happen in the else branch.)

Thanks a lot!

Yeah I got it back to front in my first post. I did make an effort in the second one though :wink:

1 Like