MongoDB atomic “findOrCreate”: findOne, insert if nonexistent, but do not update












92














as the title says, I want to perform a find (one) for a document, by _id, and if doesn't exist, have it created, then whether it was found or was created, have it returned in the callback.



I don't want to update it if it exists, as I've read findAndModify does. I have seen many other questions on Stackoverflow regarding this but again, don't wish to update anything.



I am unsure if by creating (of not existing), THAT is actually the update everyone is talking about, it's all so confuzzling :(










share|improve this question





























    92














    as the title says, I want to perform a find (one) for a document, by _id, and if doesn't exist, have it created, then whether it was found or was created, have it returned in the callback.



    I don't want to update it if it exists, as I've read findAndModify does. I have seen many other questions on Stackoverflow regarding this but again, don't wish to update anything.



    I am unsure if by creating (of not existing), THAT is actually the update everyone is talking about, it's all so confuzzling :(










    share|improve this question



























      92












      92








      92


      38





      as the title says, I want to perform a find (one) for a document, by _id, and if doesn't exist, have it created, then whether it was found or was created, have it returned in the callback.



      I don't want to update it if it exists, as I've read findAndModify does. I have seen many other questions on Stackoverflow regarding this but again, don't wish to update anything.



      I am unsure if by creating (of not existing), THAT is actually the update everyone is talking about, it's all so confuzzling :(










      share|improve this question















      as the title says, I want to perform a find (one) for a document, by _id, and if doesn't exist, have it created, then whether it was found or was created, have it returned in the callback.



      I don't want to update it if it exists, as I've read findAndModify does. I have seen many other questions on Stackoverflow regarding this but again, don't wish to update anything.



      I am unsure if by creating (of not existing), THAT is actually the update everyone is talking about, it's all so confuzzling :(







      node.js mongodb






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Sep 28 '13 at 14:11









      numbers1311407

      27.8k77681




      27.8k77681










      asked May 3 '13 at 12:23









      Discipol

      1,63811736




      1,63811736
























          4 Answers
          4






          active

          oldest

          votes


















          167














          Beginning with MongoDB 2.4, it's no longer necessary to rely on a unique index (or any other workaround) for atomic findOrCreate like operations.



          This is thanks to the $setOnInsert operator new to 2.4, which allows you to specify updates which should only happen when inserting documents.



          This, combined with the upsert option, means you can use findAndModify to achieve an atomic findOrCreate-like operation.



          db.collection.findAndModify({
          query: { _id: "some potentially existing id" },
          update: {
          $setOnInsert: { foo: "bar" }
          },
          new: true, // return new doc if one is upserted
          upsert: true // insert the document if it does not exist
          })


          As $setOnInsert only affects documents being inserted, if an existing document is found, no modification will occur. If no document exists, it will upsert one with the specified _id, then perform the insert only set. In both cases, the document is returned.






          share|improve this answer



















          • 2




            @Gank if you're using the mongodb native driver for node the syntax would be more like collection.findAndModify({_id:'theId'}, <your sort opts>, {$setOnInsert:{foo: 'bar'}}, {new:true, upsert:true}, callback). See the docs
            – numbers1311407
            Jun 3 '14 at 13:12








          • 6




            Is there a way to know if the document has been updated or inserted ?
            – doom
            Sep 10 '14 at 23:07






          • 3




            If you want to check if the query above(db.collection.findAndModify({query: {_id: "some potentially existing id"}, update: {$setOnInsert: {foo: "bar"}}, new: true, upsert: true})) insert(upsert)ed a document, you should consider using db.collection.updateOne({_id: "some potentially existing id"}, {$setOnInsert: {foo: "bar"}}, {upsert: true}). It returns {"acknowledged": true, "matchedCount": 0, "modifiedCount": 0, "upsertedId": ObjectId("for newly inserted one")} if the doc inserted, {"acknowledged": true, "matchedCount": 1, "modifiedCount": 0} if the doc already exists.
            – K._
            Jul 18 '16 at 11:38








          • 3




            seems to be deprecated in flavor of findOneAndUpdate, findOneAndReplace or findOneAndDelete
            – Ravshan Samandarov
            Nov 4 '16 at 12:45






          • 2




            One needs to be careful here, though. This only works if the selector of the findAndModify/findOneAndUpdate/updateOne uniquely identifies one document by _id. Otherwise the upsert is split up on the server into a query and an update/insert. The update will still be atomic. But the query and the update together will not be executed atomically.
            – Anon
            Apr 25 '17 at 20:14



















          5














          Its a bit dirty, but you can just insert it.



          Be sure that the key has a unique index on it (if you use the _id it's ok, it's already unique).



          In this way if the element is already present it will return an exception that you can catch.



          If it isn't present, the new document will be inserted.



          Updated: a detailed explanation of this technique on the MongoDB Documentation






          share|improve this answer























          • ok, thats a good idea, but for the pre-existing value it will return an error but NOT the value itself, right?
            – Discipol
            May 3 '13 at 14:41






          • 3




            This is actually one of the recommended solutions for isolated sequences of operations (find then create if not found, presumably) docs.mongodb.org/manual/tutorial/isolate-sequence-of-operations
            – numbers1311407
            May 3 '13 at 14:43










          • @Discipol if you want to do a set of atomic operations, you should first lock the Document, then modify it, and at the end release it. This will require more queries, but you can optimize for the best case scenario and do only 1-2 queries most of the times. see: docs.mongodb.org/manual/tutorial/perform-two-phase-commits
            – Madarco
            May 3 '13 at 15:21





















          0














          Here's what I did (Ruby MongoDB driver):



          $db[:tags].update_one({:tag => 'flat'}, {'$set' => {:tag => 'earth' }}, { :upsert => true })}



          It will update it if it exists, and insert it if it doesn't.






          share|improve this answer





























            0














            Using the latest driver (> version 2), you'll use findOneAndUpdate as findAndModify was deprecated. The new method takes 3 arguments, the filter, the update object (which contains your default properties, that should be inserted for a new object), and options where you have to specify the upsert operation.



            Using the promise syntax, it looks like this:



            const result = await collection.findOneAndUpdate(
            { _id: new ObjectId(id) },
            {
            $setOnInsert: { foo: "bar" },
            },
            {
            returnOriginal: false,
            upsert: true,
            }
            );

            const newOrUpdatedDocument = result.value;





            share|improve this answer





















              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f16358857%2fmongodb-atomic-findorcreate-findone-insert-if-nonexistent-but-do-not-update%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              4 Answers
              4






              active

              oldest

              votes








              4 Answers
              4






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              167














              Beginning with MongoDB 2.4, it's no longer necessary to rely on a unique index (or any other workaround) for atomic findOrCreate like operations.



              This is thanks to the $setOnInsert operator new to 2.4, which allows you to specify updates which should only happen when inserting documents.



              This, combined with the upsert option, means you can use findAndModify to achieve an atomic findOrCreate-like operation.



              db.collection.findAndModify({
              query: { _id: "some potentially existing id" },
              update: {
              $setOnInsert: { foo: "bar" }
              },
              new: true, // return new doc if one is upserted
              upsert: true // insert the document if it does not exist
              })


              As $setOnInsert only affects documents being inserted, if an existing document is found, no modification will occur. If no document exists, it will upsert one with the specified _id, then perform the insert only set. In both cases, the document is returned.






              share|improve this answer



















              • 2




                @Gank if you're using the mongodb native driver for node the syntax would be more like collection.findAndModify({_id:'theId'}, <your sort opts>, {$setOnInsert:{foo: 'bar'}}, {new:true, upsert:true}, callback). See the docs
                – numbers1311407
                Jun 3 '14 at 13:12








              • 6




                Is there a way to know if the document has been updated or inserted ?
                – doom
                Sep 10 '14 at 23:07






              • 3




                If you want to check if the query above(db.collection.findAndModify({query: {_id: "some potentially existing id"}, update: {$setOnInsert: {foo: "bar"}}, new: true, upsert: true})) insert(upsert)ed a document, you should consider using db.collection.updateOne({_id: "some potentially existing id"}, {$setOnInsert: {foo: "bar"}}, {upsert: true}). It returns {"acknowledged": true, "matchedCount": 0, "modifiedCount": 0, "upsertedId": ObjectId("for newly inserted one")} if the doc inserted, {"acknowledged": true, "matchedCount": 1, "modifiedCount": 0} if the doc already exists.
                – K._
                Jul 18 '16 at 11:38








              • 3




                seems to be deprecated in flavor of findOneAndUpdate, findOneAndReplace or findOneAndDelete
                – Ravshan Samandarov
                Nov 4 '16 at 12:45






              • 2




                One needs to be careful here, though. This only works if the selector of the findAndModify/findOneAndUpdate/updateOne uniquely identifies one document by _id. Otherwise the upsert is split up on the server into a query and an update/insert. The update will still be atomic. But the query and the update together will not be executed atomically.
                – Anon
                Apr 25 '17 at 20:14
















              167














              Beginning with MongoDB 2.4, it's no longer necessary to rely on a unique index (or any other workaround) for atomic findOrCreate like operations.



              This is thanks to the $setOnInsert operator new to 2.4, which allows you to specify updates which should only happen when inserting documents.



              This, combined with the upsert option, means you can use findAndModify to achieve an atomic findOrCreate-like operation.



              db.collection.findAndModify({
              query: { _id: "some potentially existing id" },
              update: {
              $setOnInsert: { foo: "bar" }
              },
              new: true, // return new doc if one is upserted
              upsert: true // insert the document if it does not exist
              })


              As $setOnInsert only affects documents being inserted, if an existing document is found, no modification will occur. If no document exists, it will upsert one with the specified _id, then perform the insert only set. In both cases, the document is returned.






              share|improve this answer



















              • 2




                @Gank if you're using the mongodb native driver for node the syntax would be more like collection.findAndModify({_id:'theId'}, <your sort opts>, {$setOnInsert:{foo: 'bar'}}, {new:true, upsert:true}, callback). See the docs
                – numbers1311407
                Jun 3 '14 at 13:12








              • 6




                Is there a way to know if the document has been updated or inserted ?
                – doom
                Sep 10 '14 at 23:07






              • 3




                If you want to check if the query above(db.collection.findAndModify({query: {_id: "some potentially existing id"}, update: {$setOnInsert: {foo: "bar"}}, new: true, upsert: true})) insert(upsert)ed a document, you should consider using db.collection.updateOne({_id: "some potentially existing id"}, {$setOnInsert: {foo: "bar"}}, {upsert: true}). It returns {"acknowledged": true, "matchedCount": 0, "modifiedCount": 0, "upsertedId": ObjectId("for newly inserted one")} if the doc inserted, {"acknowledged": true, "matchedCount": 1, "modifiedCount": 0} if the doc already exists.
                – K._
                Jul 18 '16 at 11:38








              • 3




                seems to be deprecated in flavor of findOneAndUpdate, findOneAndReplace or findOneAndDelete
                – Ravshan Samandarov
                Nov 4 '16 at 12:45






              • 2




                One needs to be careful here, though. This only works if the selector of the findAndModify/findOneAndUpdate/updateOne uniquely identifies one document by _id. Otherwise the upsert is split up on the server into a query and an update/insert. The update will still be atomic. But the query and the update together will not be executed atomically.
                – Anon
                Apr 25 '17 at 20:14














              167












              167








              167






              Beginning with MongoDB 2.4, it's no longer necessary to rely on a unique index (or any other workaround) for atomic findOrCreate like operations.



              This is thanks to the $setOnInsert operator new to 2.4, which allows you to specify updates which should only happen when inserting documents.



              This, combined with the upsert option, means you can use findAndModify to achieve an atomic findOrCreate-like operation.



              db.collection.findAndModify({
              query: { _id: "some potentially existing id" },
              update: {
              $setOnInsert: { foo: "bar" }
              },
              new: true, // return new doc if one is upserted
              upsert: true // insert the document if it does not exist
              })


              As $setOnInsert only affects documents being inserted, if an existing document is found, no modification will occur. If no document exists, it will upsert one with the specified _id, then perform the insert only set. In both cases, the document is returned.






              share|improve this answer














              Beginning with MongoDB 2.4, it's no longer necessary to rely on a unique index (or any other workaround) for atomic findOrCreate like operations.



              This is thanks to the $setOnInsert operator new to 2.4, which allows you to specify updates which should only happen when inserting documents.



              This, combined with the upsert option, means you can use findAndModify to achieve an atomic findOrCreate-like operation.



              db.collection.findAndModify({
              query: { _id: "some potentially existing id" },
              update: {
              $setOnInsert: { foo: "bar" }
              },
              new: true, // return new doc if one is upserted
              upsert: true // insert the document if it does not exist
              })


              As $setOnInsert only affects documents being inserted, if an existing document is found, no modification will occur. If no document exists, it will upsert one with the specified _id, then perform the insert only set. In both cases, the document is returned.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Apr 15 '14 at 17:11

























              answered May 3 '13 at 15:45









              numbers1311407

              27.8k77681




              27.8k77681








              • 2




                @Gank if you're using the mongodb native driver for node the syntax would be more like collection.findAndModify({_id:'theId'}, <your sort opts>, {$setOnInsert:{foo: 'bar'}}, {new:true, upsert:true}, callback). See the docs
                – numbers1311407
                Jun 3 '14 at 13:12








              • 6




                Is there a way to know if the document has been updated or inserted ?
                – doom
                Sep 10 '14 at 23:07






              • 3




                If you want to check if the query above(db.collection.findAndModify({query: {_id: "some potentially existing id"}, update: {$setOnInsert: {foo: "bar"}}, new: true, upsert: true})) insert(upsert)ed a document, you should consider using db.collection.updateOne({_id: "some potentially existing id"}, {$setOnInsert: {foo: "bar"}}, {upsert: true}). It returns {"acknowledged": true, "matchedCount": 0, "modifiedCount": 0, "upsertedId": ObjectId("for newly inserted one")} if the doc inserted, {"acknowledged": true, "matchedCount": 1, "modifiedCount": 0} if the doc already exists.
                – K._
                Jul 18 '16 at 11:38








              • 3




                seems to be deprecated in flavor of findOneAndUpdate, findOneAndReplace or findOneAndDelete
                – Ravshan Samandarov
                Nov 4 '16 at 12:45






              • 2




                One needs to be careful here, though. This only works if the selector of the findAndModify/findOneAndUpdate/updateOne uniquely identifies one document by _id. Otherwise the upsert is split up on the server into a query and an update/insert. The update will still be atomic. But the query and the update together will not be executed atomically.
                – Anon
                Apr 25 '17 at 20:14














              • 2




                @Gank if you're using the mongodb native driver for node the syntax would be more like collection.findAndModify({_id:'theId'}, <your sort opts>, {$setOnInsert:{foo: 'bar'}}, {new:true, upsert:true}, callback). See the docs
                – numbers1311407
                Jun 3 '14 at 13:12








              • 6




                Is there a way to know if the document has been updated or inserted ?
                – doom
                Sep 10 '14 at 23:07






              • 3




                If you want to check if the query above(db.collection.findAndModify({query: {_id: "some potentially existing id"}, update: {$setOnInsert: {foo: "bar"}}, new: true, upsert: true})) insert(upsert)ed a document, you should consider using db.collection.updateOne({_id: "some potentially existing id"}, {$setOnInsert: {foo: "bar"}}, {upsert: true}). It returns {"acknowledged": true, "matchedCount": 0, "modifiedCount": 0, "upsertedId": ObjectId("for newly inserted one")} if the doc inserted, {"acknowledged": true, "matchedCount": 1, "modifiedCount": 0} if the doc already exists.
                – K._
                Jul 18 '16 at 11:38








              • 3




                seems to be deprecated in flavor of findOneAndUpdate, findOneAndReplace or findOneAndDelete
                – Ravshan Samandarov
                Nov 4 '16 at 12:45






              • 2




                One needs to be careful here, though. This only works if the selector of the findAndModify/findOneAndUpdate/updateOne uniquely identifies one document by _id. Otherwise the upsert is split up on the server into a query and an update/insert. The update will still be atomic. But the query and the update together will not be executed atomically.
                – Anon
                Apr 25 '17 at 20:14








              2




              2




              @Gank if you're using the mongodb native driver for node the syntax would be more like collection.findAndModify({_id:'theId'}, <your sort opts>, {$setOnInsert:{foo: 'bar'}}, {new:true, upsert:true}, callback). See the docs
              – numbers1311407
              Jun 3 '14 at 13:12






              @Gank if you're using the mongodb native driver for node the syntax would be more like collection.findAndModify({_id:'theId'}, <your sort opts>, {$setOnInsert:{foo: 'bar'}}, {new:true, upsert:true}, callback). See the docs
              – numbers1311407
              Jun 3 '14 at 13:12






              6




              6




              Is there a way to know if the document has been updated or inserted ?
              – doom
              Sep 10 '14 at 23:07




              Is there a way to know if the document has been updated or inserted ?
              – doom
              Sep 10 '14 at 23:07




              3




              3




              If you want to check if the query above(db.collection.findAndModify({query: {_id: "some potentially existing id"}, update: {$setOnInsert: {foo: "bar"}}, new: true, upsert: true})) insert(upsert)ed a document, you should consider using db.collection.updateOne({_id: "some potentially existing id"}, {$setOnInsert: {foo: "bar"}}, {upsert: true}). It returns {"acknowledged": true, "matchedCount": 0, "modifiedCount": 0, "upsertedId": ObjectId("for newly inserted one")} if the doc inserted, {"acknowledged": true, "matchedCount": 1, "modifiedCount": 0} if the doc already exists.
              – K._
              Jul 18 '16 at 11:38






              If you want to check if the query above(db.collection.findAndModify({query: {_id: "some potentially existing id"}, update: {$setOnInsert: {foo: "bar"}}, new: true, upsert: true})) insert(upsert)ed a document, you should consider using db.collection.updateOne({_id: "some potentially existing id"}, {$setOnInsert: {foo: "bar"}}, {upsert: true}). It returns {"acknowledged": true, "matchedCount": 0, "modifiedCount": 0, "upsertedId": ObjectId("for newly inserted one")} if the doc inserted, {"acknowledged": true, "matchedCount": 1, "modifiedCount": 0} if the doc already exists.
              – K._
              Jul 18 '16 at 11:38






              3




              3




              seems to be deprecated in flavor of findOneAndUpdate, findOneAndReplace or findOneAndDelete
              – Ravshan Samandarov
              Nov 4 '16 at 12:45




              seems to be deprecated in flavor of findOneAndUpdate, findOneAndReplace or findOneAndDelete
              – Ravshan Samandarov
              Nov 4 '16 at 12:45




              2




              2




              One needs to be careful here, though. This only works if the selector of the findAndModify/findOneAndUpdate/updateOne uniquely identifies one document by _id. Otherwise the upsert is split up on the server into a query and an update/insert. The update will still be atomic. But the query and the update together will not be executed atomically.
              – Anon
              Apr 25 '17 at 20:14




              One needs to be careful here, though. This only works if the selector of the findAndModify/findOneAndUpdate/updateOne uniquely identifies one document by _id. Otherwise the upsert is split up on the server into a query and an update/insert. The update will still be atomic. But the query and the update together will not be executed atomically.
              – Anon
              Apr 25 '17 at 20:14













              5














              Its a bit dirty, but you can just insert it.



              Be sure that the key has a unique index on it (if you use the _id it's ok, it's already unique).



              In this way if the element is already present it will return an exception that you can catch.



              If it isn't present, the new document will be inserted.



              Updated: a detailed explanation of this technique on the MongoDB Documentation






              share|improve this answer























              • ok, thats a good idea, but for the pre-existing value it will return an error but NOT the value itself, right?
                – Discipol
                May 3 '13 at 14:41






              • 3




                This is actually one of the recommended solutions for isolated sequences of operations (find then create if not found, presumably) docs.mongodb.org/manual/tutorial/isolate-sequence-of-operations
                – numbers1311407
                May 3 '13 at 14:43










              • @Discipol if you want to do a set of atomic operations, you should first lock the Document, then modify it, and at the end release it. This will require more queries, but you can optimize for the best case scenario and do only 1-2 queries most of the times. see: docs.mongodb.org/manual/tutorial/perform-two-phase-commits
                – Madarco
                May 3 '13 at 15:21


















              5














              Its a bit dirty, but you can just insert it.



              Be sure that the key has a unique index on it (if you use the _id it's ok, it's already unique).



              In this way if the element is already present it will return an exception that you can catch.



              If it isn't present, the new document will be inserted.



              Updated: a detailed explanation of this technique on the MongoDB Documentation






              share|improve this answer























              • ok, thats a good idea, but for the pre-existing value it will return an error but NOT the value itself, right?
                – Discipol
                May 3 '13 at 14:41






              • 3




                This is actually one of the recommended solutions for isolated sequences of operations (find then create if not found, presumably) docs.mongodb.org/manual/tutorial/isolate-sequence-of-operations
                – numbers1311407
                May 3 '13 at 14:43










              • @Discipol if you want to do a set of atomic operations, you should first lock the Document, then modify it, and at the end release it. This will require more queries, but you can optimize for the best case scenario and do only 1-2 queries most of the times. see: docs.mongodb.org/manual/tutorial/perform-two-phase-commits
                – Madarco
                May 3 '13 at 15:21
















              5












              5








              5






              Its a bit dirty, but you can just insert it.



              Be sure that the key has a unique index on it (if you use the _id it's ok, it's already unique).



              In this way if the element is already present it will return an exception that you can catch.



              If it isn't present, the new document will be inserted.



              Updated: a detailed explanation of this technique on the MongoDB Documentation






              share|improve this answer














              Its a bit dirty, but you can just insert it.



              Be sure that the key has a unique index on it (if you use the _id it's ok, it's already unique).



              In this way if the element is already present it will return an exception that you can catch.



              If it isn't present, the new document will be inserted.



              Updated: a detailed explanation of this technique on the MongoDB Documentation







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Dec 18 '13 at 12:32









              Joe

              29.6k18116191




              29.6k18116191










              answered May 3 '13 at 14:05









              Madarco

              1,7751426




              1,7751426












              • ok, thats a good idea, but for the pre-existing value it will return an error but NOT the value itself, right?
                – Discipol
                May 3 '13 at 14:41






              • 3




                This is actually one of the recommended solutions for isolated sequences of operations (find then create if not found, presumably) docs.mongodb.org/manual/tutorial/isolate-sequence-of-operations
                – numbers1311407
                May 3 '13 at 14:43










              • @Discipol if you want to do a set of atomic operations, you should first lock the Document, then modify it, and at the end release it. This will require more queries, but you can optimize for the best case scenario and do only 1-2 queries most of the times. see: docs.mongodb.org/manual/tutorial/perform-two-phase-commits
                – Madarco
                May 3 '13 at 15:21




















              • ok, thats a good idea, but for the pre-existing value it will return an error but NOT the value itself, right?
                – Discipol
                May 3 '13 at 14:41






              • 3




                This is actually one of the recommended solutions for isolated sequences of operations (find then create if not found, presumably) docs.mongodb.org/manual/tutorial/isolate-sequence-of-operations
                – numbers1311407
                May 3 '13 at 14:43










              • @Discipol if you want to do a set of atomic operations, you should first lock the Document, then modify it, and at the end release it. This will require more queries, but you can optimize for the best case scenario and do only 1-2 queries most of the times. see: docs.mongodb.org/manual/tutorial/perform-two-phase-commits
                – Madarco
                May 3 '13 at 15:21


















              ok, thats a good idea, but for the pre-existing value it will return an error but NOT the value itself, right?
              – Discipol
              May 3 '13 at 14:41




              ok, thats a good idea, but for the pre-existing value it will return an error but NOT the value itself, right?
              – Discipol
              May 3 '13 at 14:41




              3




              3




              This is actually one of the recommended solutions for isolated sequences of operations (find then create if not found, presumably) docs.mongodb.org/manual/tutorial/isolate-sequence-of-operations
              – numbers1311407
              May 3 '13 at 14:43




              This is actually one of the recommended solutions for isolated sequences of operations (find then create if not found, presumably) docs.mongodb.org/manual/tutorial/isolate-sequence-of-operations
              – numbers1311407
              May 3 '13 at 14:43












              @Discipol if you want to do a set of atomic operations, you should first lock the Document, then modify it, and at the end release it. This will require more queries, but you can optimize for the best case scenario and do only 1-2 queries most of the times. see: docs.mongodb.org/manual/tutorial/perform-two-phase-commits
              – Madarco
              May 3 '13 at 15:21






              @Discipol if you want to do a set of atomic operations, you should first lock the Document, then modify it, and at the end release it. This will require more queries, but you can optimize for the best case scenario and do only 1-2 queries most of the times. see: docs.mongodb.org/manual/tutorial/perform-two-phase-commits
              – Madarco
              May 3 '13 at 15:21













              0














              Here's what I did (Ruby MongoDB driver):



              $db[:tags].update_one({:tag => 'flat'}, {'$set' => {:tag => 'earth' }}, { :upsert => true })}



              It will update it if it exists, and insert it if it doesn't.






              share|improve this answer


























                0














                Here's what I did (Ruby MongoDB driver):



                $db[:tags].update_one({:tag => 'flat'}, {'$set' => {:tag => 'earth' }}, { :upsert => true })}



                It will update it if it exists, and insert it if it doesn't.






                share|improve this answer
























                  0












                  0








                  0






                  Here's what I did (Ruby MongoDB driver):



                  $db[:tags].update_one({:tag => 'flat'}, {'$set' => {:tag => 'earth' }}, { :upsert => true })}



                  It will update it if it exists, and insert it if it doesn't.






                  share|improve this answer












                  Here's what I did (Ruby MongoDB driver):



                  $db[:tags].update_one({:tag => 'flat'}, {'$set' => {:tag => 'earth' }}, { :upsert => true })}



                  It will update it if it exists, and insert it if it doesn't.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Dec 6 '16 at 18:45









                  Vidar

                  13828




                  13828























                      0














                      Using the latest driver (> version 2), you'll use findOneAndUpdate as findAndModify was deprecated. The new method takes 3 arguments, the filter, the update object (which contains your default properties, that should be inserted for a new object), and options where you have to specify the upsert operation.



                      Using the promise syntax, it looks like this:



                      const result = await collection.findOneAndUpdate(
                      { _id: new ObjectId(id) },
                      {
                      $setOnInsert: { foo: "bar" },
                      },
                      {
                      returnOriginal: false,
                      upsert: true,
                      }
                      );

                      const newOrUpdatedDocument = result.value;





                      share|improve this answer


























                        0














                        Using the latest driver (> version 2), you'll use findOneAndUpdate as findAndModify was deprecated. The new method takes 3 arguments, the filter, the update object (which contains your default properties, that should be inserted for a new object), and options where you have to specify the upsert operation.



                        Using the promise syntax, it looks like this:



                        const result = await collection.findOneAndUpdate(
                        { _id: new ObjectId(id) },
                        {
                        $setOnInsert: { foo: "bar" },
                        },
                        {
                        returnOriginal: false,
                        upsert: true,
                        }
                        );

                        const newOrUpdatedDocument = result.value;





                        share|improve this answer
























                          0












                          0








                          0






                          Using the latest driver (> version 2), you'll use findOneAndUpdate as findAndModify was deprecated. The new method takes 3 arguments, the filter, the update object (which contains your default properties, that should be inserted for a new object), and options where you have to specify the upsert operation.



                          Using the promise syntax, it looks like this:



                          const result = await collection.findOneAndUpdate(
                          { _id: new ObjectId(id) },
                          {
                          $setOnInsert: { foo: "bar" },
                          },
                          {
                          returnOriginal: false,
                          upsert: true,
                          }
                          );

                          const newOrUpdatedDocument = result.value;





                          share|improve this answer












                          Using the latest driver (> version 2), you'll use findOneAndUpdate as findAndModify was deprecated. The new method takes 3 arguments, the filter, the update object (which contains your default properties, that should be inserted for a new object), and options where you have to specify the upsert operation.



                          Using the promise syntax, it looks like this:



                          const result = await collection.findOneAndUpdate(
                          { _id: new ObjectId(id) },
                          {
                          $setOnInsert: { foo: "bar" },
                          },
                          {
                          returnOriginal: false,
                          upsert: true,
                          }
                          );

                          const newOrUpdatedDocument = result.value;






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Apr 14 at 11:15









                          hansmaad

                          10.8k73477




                          10.8k73477






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f16358857%2fmongodb-atomic-findorcreate-findone-insert-if-nonexistent-but-do-not-update%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Florida Star v. B. J. F.

                              Danny Elfman

                              Lugert, Oklahoma