0

I'm saving data to my db and struggling with updating existing documents. I'd like my app to check if the document already exists and if the info has changed. If the document exists and the info hasn't changed, app skips the document. It's working ok. I'd also want it to update the document in case the data has changed. How can I achieve that?

This is my code responsible for saving the data:

const hash = md5(price + km);

const query = {
            hash: hash
          },
          options = { upsert: true };

        Car.findOneAndUpdate(query, options, function(error, result) {
          if (!error) {
            if (!result) {
              result = new Car({
                make: make,
                model: model,
                year: yearInt,
                km: kmInt,
                price: priceInt,
                currency: currency,
                link: link,
                imageUrls: images,
                hash: hash
              });
              result.save(function(error) {
                if (!error) {
                  console.log('car saved!' + result);
                } else {
                  throw error;
                }
              });
            } else {
              console.log('already in db');
            }
          } else {
            console.log(error);
          }
        });

As you can see, I'm using md5 package to create a hash for every car I'm saving to database. It uses the km and price combination to create the hash. So when the data for "km" or "price" variables changes, the hash also changes. And when it does, I'd like to update the km and/or price data in my db. Should I use the _id instead of hash to find the document?

I also trie something like this to see if the hash had changed but wasn't able to get it right:

if (query.hash != result.hash) {
                    car.update({
                      make: make,
                      model: model,
                      year: yearInt,
                      km: kmInt,
                      price: priceInt,
                      currency: currency,
                      link: link,
                      imageUrls: images,
                      hash: hash
                    });
                  }

I'd be grateful if someone would push me in to the right direction with this.

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
lr_optim
  • 299
  • 1
  • 10
  • 30
  • The syntax usage for [`findOneAndUpdate()`](https://mongoosejs.com/docs/api/model.html#model_Model.findOneAndUpdate) is incorrect. It's `[conditions],[update],[options]`. You are missing the `update` part which actually does everything for you. The `options` should have `{ upsert: true, new: true }` in order to "upsert" ( which basically means, update if exists otherwise create a new one ) and the `new` because you want the "modfied" document returned. No need to have fallback logic to `new Car()` or anything like that. – Neil Lunn Sep 30 '19 at 08:45
  • Can I use the update option to check if some certain fields are changed and if they are - update them? – lr_optim Sep 30 '19 at 09:10
  • MongoDB does not actually "update" anything if the value sent to be changed is exactly the same as what is already there. Note also as shown in existing answers the `$setOnInsert` specifies things that should only be touched on "insertion" and not touched at all by any other update operator. So you have that option. You probably should familiarize yourself with the [atomic update operators](https://docs.mongodb.com/manual/reference/operator/update-field/), since your current usage does not indicate you are particularly aware of them. – Neil Lunn Sep 30 '19 at 09:16

0 Answers0