Race condition in monodb updates?

I seem to have a problem with batch-updates that I run in the background. Periodically, a job runs that goes over all elements in one collection and updates them.

I wrote a few helper functions, which should ensure that only available resources are taken and the collection is updated properly:

	static getStore(warehouse, resource) {
		return warehouse.storage.find(x => x.resource == resource)
	}

	static getStoreAmount(warehouse, resource) {
		let store = this.getStore(warehouse, resource)
		if (store) {
			return store.amount
		} else {
			return 0
		}
	}

	static addToStorage(warehouse, resource, amount) {
		if (amount <= 0) return true;
		console.log("adding "+amount+" "+resource)
		let store = this.getStore(warehouse, resource)

		// TODO: check if enough storage space is left
		// FIXME: somehow, something created a duplicate entry for grain here (from 2 fields) - async database calls?
					// with 3 fields, it gets added 3 times - definitely reliably bugged :-(
		// FIXME: somehow, despite adding twice, nothign was left - again async update call just before $pull'ing it?

		if (store) {
			Warehouses.update({"_id":warehouse._id, "storage.resource": resource}, {
				$set: {
					"storage.$.amount": store.amount + amount
				}
			})
		} else {
			Warehouses.update({"_id":warehouse._id}, {
				$push: {
					storage: {
						resource: resource,
						amount: amount,
						buy: { amount: 0, price: 0 },
						sell: { amount: 0, price: 0 }
					}
				}
			})
		}
		return true
	}

	static checkTakeFromStorage(warehouse, resource, amount, min=1) {
		if (amount <= 0) return 0;
		let have = this.getStoreAmount(warehouse,resource)
		if (have < min) {
			return 0
		}
		console.log("taking "+amount+" "+resource)
		if (amount >= have) {
			// FIXME: don't pull if we have buy or sell values !
			amount = have
			// $pull is tricky because of meteor limitations, so here is a workaround I found on the Internet:
			let raw = Warehouses.rawCollection()
			let findOneAndUpdate = Meteor.wrapAsync(raw.findOneAndUpdate, raw)
			findOneAndUpdate({_id: warehouse._id}, {
				$pull: { storage: { resource: resource }}
			})
		} else {
			Warehouses.update({"_id":warehouse._id, "storage.resource": resource}, {
				$set: {
					"storage.$.amount": have - amount
				}
			})
		}

		return amount
	}

the data structure is like this:

warehouses {
 ...various things...
storage: [
{ resource: "a", amount: 123 },
{ resource: "b", amount: 456 },
...
]
}

however, when I run the batch job, contrary to my intended code, multiple entries are made in the storage table for the same resource. I’m probably doing my updates in a stupid way and there is probably a proper meteor/mongo way to do them that guarantees this cannot happen, but I couldn’t find it when I searched for it, due to the fact that I update an array in an embedded document.