title: Mongoose: atomic FindOne-Or-Insert(), do not update existing instance if found
body: <p>In Mongoose, I am seeking to perform atomically a way to <code>Model.FindOne-Or-Insert()</code>, similar functionality and signature as currently available <a href="https://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate" rel="nofollow noreferrer"><code>Model.FindOneAndUpdate()</code></a> except if an instance exists (i.e. matches <code>filter</code>) then <strong>do not update using provided <code>object</code></strong> but return instance found as is, and if not exists (i.e. no match with <code>filter</code>) then insert <code>object</code> and return new instance.</p>
  
  <p>I could not find a way using <a href="https://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate" rel="nofollow noreferrer"><code>Model.FindOneAndUpdate()</code></a> not to perform an update to an existing instance by trying out variances to its <code>options</code> and not providing fields to <code>object</code> that preferred not to update if instance exists.</p>
  
  <p>So, my current <strong>non-atomic</strong> workaround is <a href="https://mongoosejs.com/docs/api.html#model_Model.findOne" rel="nofollow noreferrer"><code>Model.FindOne()</code></a> and if not found then perform <a href="https://mongoosejs.com/docs/api.html#document_Document-save" rel="nofollow noreferrer"><code>Document.save()</code></a>.</p>
  
  <pre><code>const Foo = DB.model('foo', FooSchema)
  
  async function findOneAndUpdateFoo(jsonFoo, next) {
  
    const filter = {
      deletedAt: null
    }
    if (jsonFoo.dsAccountId) {
      filter.dsAccountId = jsonFoo.dsAccountId
    }
    if (jsonIntegration.dsUserId) {
      filter.dsUserId = jsonIntegration.dsUserId
    }
    if (jsonFoo.providerId) {
      filter.providerId = jsonFoo.providerId
    }
  
    const fooDoc = {
      name: jsonFoo.name,
      dsAccountId: jsonFoo.dsAccountId,
      dsUserId: jsonFoo.dsUserId,
      providerId: jsonFoo.providerId,
      providerName: jsonFoo.providerName,
  
      // Most of these fields could be empty
      accessToken: jsonFoo.accessToken,
      refreshToken: jsonFoo.refreshToken,
      scope: jsonFoo.scope,
      tokenType: jsonFoo.tokenType,
      expiresAt: jsonFoo.expiresAt
    }
  
    return await Foo.findOneAndUpdate(
      filter, // find a document with that filter
      fooDoc, // document to insert when nothing was found
      { upsert: true, new: true, runValidators: true } // options
    )
      .catch(next)
  }
  </code></pre>
  
  <p>Suggestions? Thank you</p>