Avoid a duplicate value when I update array using $push on MongoDB
Asked Answered
C

3

21

I want to push some values into array using Python.
Maybe next time when i update the array ,it will insert some values exists ,so it will got some duplicate values.
I want to know is there anyway to avoid duplicate values.
Should I use db.collection.find() to determine whether I should insert or not ?

db.graph.insert_one({"user_id": a.url}, )
for j in a.followers:
    db.graph.update({"user_id": a.url}, {"$push": {"following": j.url}})
Chew answered 9/4, 2016 at 15:10 Comment(0)
G
36

The best way to do this is using $addToSet operator which ensures that there are no duplicate items added to the set and the $each modifier to add multiple values to the"following" array.

urls = [j.url for j in a.followers]
db.graph.update_one({"user_id": a.url}, {"$addToSet": {"following": {"$each": urls}}})

also you should use the update_one method because update is deprecated.

Getter answered 9/4, 2016 at 15:44 Comment(3)
is it possible with findOneAndUpdate ?Gabbie
how do you remove ?Countersignature
Just a side note, this might work well for the example in question - with primitive value types (string, integer) - but might not work well with arrays containing documents. In such a case, comparison done for the whole document and checks if existing documents have the same properties, exactly in the same order and exactly the same values. Meaning, you can't use some unique property of document in an array.Kastroprauxel
P
6

I think, that you can use $addToSet operator: https://docs.mongodb.org/manual/reference/operator/update/addToSet/

Proudhon answered 9/4, 2016 at 15:12 Comment(1)
Try to give an example, rather than just a URL. That way, answers aren't reliant on URLs remaining valid.Hast
J
0

I'm lazy ass, so I'm going to paste here the code i use. Don't mind the language. The underline logic is similar.

// array of object prevent duplication 1------------------------------

Dict_target_schema.index(
  { user_id: 1, wid: 1, w: 1, "exp.r_id": 1 },
  { unique: true }
);
let result = await Dict_target.findOneAndUpdate(
  { user_id, wid, w, "exp.r_id": { $ne: article_id } },
  {
    $push: {
      exp: {
        r_id: article_id,
      },
    },
  },
  {
    upsert: true,
    new: true,
  }
);

// array of object prevent duplication 2-----------------

Dict_target_schema.index(
  { user_id: 1, wid: 1, w: 1 },
  { unique: true }
);
let result = await Dict_target.findOneAndUpdate(
  {
    user_id,
    wid,
    w,
    exp: { $not: { $elemMatch: { r_id: article_id } } },
  },
  {
    $push: {
      exp: {
        r_id: article_id,
      },
    },
  },
  {
    upsert: true,
    new: true,
  }
);
Jameyjami answered 22/7 at 7:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.