skip to Main Content

Hi i’ve been looking for a way to

  1. search through a collection for a document containing an email
  2. if no documents exist with that email, create one and return the document, if the document does exist already, return that original document.

updateOne() creates the document if it doesn’t exist but it doesn’t return the newly created document. Whereas, findOneAndUpdate() returns what i need but overwrites the document if it exists already. findOne() returns the document if it finds one, but it doesn’t upsert. I feel like i am missing a pretty basic command here.

.findOneAndUpdate(
        {
          email: email,
        },
        {
          $setOnInsert: {
           data: data
          },
        },
        { upsert: true }
      );

and also

.updateOne(
        {
          email: email,
        },
        {
          $setOnInsert: {
           data:data
          },
        },
        { upsert: true }
      );

2

Answers


  1. Chosen as BEST ANSWER

    Making the email field a "unique index" and then using insert one fixed the problem for me.


  2. Usually I use findOne({email: "[email protected]"}) and then test the returned document.

    In php as follows:

    $exists = $collection->findOne(['email' => "[email protected]"]);
    if ($exists) {
        $collection-> updateOne(
            ['email' => '[email protected]'],
            [ '$set' => ['data' => 'tararara'],
        );
    } else {
        $newDocument = array( 
            'email' => '[email protected]',
            'data' => 'new_data',
        );
        $collection->insertOne($newDocument);
    }
    
    

    In this way, you already have the newly inserted document and the data of the currently existing document.

    If there is a better way, I would be very interested in it.

    Hope this helps!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search