Mongodb update all the documents with unique id
Asked Answered
B

3

5

I have collection with name products with almost 100k documents. I want to introduce a new key called secondaryKey with unique value uuid in all the documents. I do this using nodejs.

Problem I am facing:-

When I try the below query,

db.collection('products').updateMany({},{"$set":{secondaryKey: uuid()}});

Here it updates all the documents with same uuid value,

I try with loop to update document one by one,but here issues is I don't have filter value in updateOne because I want to update all the documents.

Can anyone please help me here. Thanks :)

Biographical answered 18/3, 2021 at 9:49 Comment(0)
F
6

If you are using MongoDB version >= 4.4 You can try this:

db.products.updateMany(
    {},
    [
        {
            $set: {
                secondaryKey: {
                    $function: {
                        body: function() {
                            return UUID().toString().split('"')[1];
                        },
                        args: [],
                        lang: "js"
                    }
                }
            }
        }
    ]
);

Output

[
  {
    "_id": ObjectId("..."),
    "secondaryKey": "f41b15b7-a0c5-43ed-9d15-69dbafc0ed29"
  },
  {
    "_id": ObjectId("..."),
    "secondaryKey": "50ae7248-a92e-4b10-be7d-126b8083ff64"
  },
  {
    "_id": ObjectId("..."),
    "secondaryKey": "fa778a1a-371b-422a-b73f-8bcff865ad8e"
  }
]
Fons answered 31/3, 2021 at 20:7 Comment(2)
Btw, This question brought me here: #66894533Fons
This only works if security.javascriptEnabled is enabled which is a requirement and not preferable method. "For a mongos instance, see security.javascriptEnabled configuration option or the --noscripting command-line option starting in MongoDB 4.4."Hallagan
V
1

Since it's not the same value you want to put in each document you have to use the loop.

In your loop, you have to update the current document of the iteration. So you have to filter with the _id in the updateOne

Venetis answered 18/3, 2021 at 10:14 Comment(1)
any way, we can achieve through updateMany by just incrementing the secondaryKey, I can use uuid later as well, just wanted a unquie secondaryKey for each document, because looping will be heavier process.Biographical
H
0

The above reply didn't work for me. Plus, it compromises security when you enable javascript on your database (see here $function and javascript enabling on database). The best way is to not overload your server, do your work on local as below:

const { nanoid, customAlphabet } = require('nanoid') 

async function asdf() {


const movies = await client.db("localhost").collection("productpost");
var result2 = []

let result = await movies.find({}).toArray()
result.forEach(element => {
    const nanoid = customAlphabet('1234567890', 10)
    console.log(element.price)
    element.price = 4
    element.id = nanoid()
    result2.push(element)
});
console.log("out reult2", result2)
await movies.deleteMany({})
await movies.insertMany(result2) 
})

It will delete any objects on your collections and update with the new ones. Using nanoid as uniqueids.

This is the database object array after adding unique id:

{  "_id": {    "$oid": "334a98519a20b05c20574dd1"  },  "attach": "[\"http://localhost:8000/be/images/2022/4/bitfinicon.png\"]",  "title": "jkn jnjn",  "description": "jnjn",  "price": 4,  "color": "After viewing I am 48.73025772956596% more satisfied with life.",  "trademark": "",  "category": "[]",  "productstate": "Published",  "createdat": {    "$date": "2022-04-03T17:40:54.743Z"  },  "language": "en"}

P.S: Please backup your collection before doing this or filter the array on your needs for not going through all collection.

Hallagan answered 4/4, 2022 at 7:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.