0

I want to check every object in the pronunciations array and check if the likes array in each object contains remove_this, then remove it from every likes array.

{
    "_id": "5a052785aa06c22429717bad",
    "word": "wordtest5",
    "__v": 0,
    "pronunciations": [
        {
            "pronunciation": "wordtest1",
            "_id": "5a052785aa06c22429717bae",
            "likes": [
                "remove_this",
                "5a0508cfcf4f6620786a3cb1"
            ],
            "rating": 1
        },
        {
            "pronunciation": "wordtest5",
            "_id": "5a0674c1053ae929db3a576c",
            "likes": [],
            "rating": 1
        },
        {
            "pronunciation": "testing5",
            "_id": "5a06770346be3d2ac6f31561",
            "likes": [
                "remove_this",
                "5a0508cfcf4f6620786a3cb1",
            ],
            "rating": 1
        }
    ]
}

I want to remove all remove_this strings inside every likes array.

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
earthyearth
  • 15
  • 1
  • 5
  • Is this a one off data cleansing excercise of something that needs to be done as part of normal operations of your application? – dnickless Nov 12 '17 at 18:23

1 Answers1

0

If this is a one off data cleansing excercise, you could simply run the following command over and over again until MongoDB says that no documents were updated:

db.collection.update({"pronunciations.likes": "remove_this"}, { $pull: { "pronunciations.$.likes": "remove_this" } })
dnickless
  • 10,733
  • 1
  • 19
  • 34
  • Yes, it is. pronunciations.likes is a reference is the 'likes' array? Do we not have to go through each object first? I'll give it a try. Thank you. – earthyearth Nov 12 '17 at 19:24
  • Not sure I understand...? Try it on some sample data! – dnickless Nov 12 '17 at 19:25
  • 1
    According to the documentation https://docs.mongodb.com/manual/reference/operator/update/positional/ the $ will only update the first entry of your array. So this would only update the entry in position 0, but not the entry in position 2. I don't think this is what you want, or is it? – Alex P. Nov 12 '17 at 19:45
  • @AlexP.: That's why I'm saying: If it's a one off then run it *multiple times* – dnickless Nov 12 '17 at 19:49
  • @dnickless I am getting "Error: Can't set headers after they are sent." after it removes the elements – earthyearth Nov 12 '17 at 20:01
  • @dnickless how do I run it multiple times in a single query statement? – earthyearth Nov 12 '17 at 20:03
  • You don't. ;) You would build a JS loop (while) around it. That's why I am saying: If it's a one off exercise then you may as well run this query several times from a different MongoDB client, e.g. Robo 3T or just mongo.exe. If you need to build something into your application, I hope someone comes with a smarter solution that mine... With respect to your "Can't set headers..." error, that's caused by some JS around your call which I would need to see first... – dnickless Nov 12 '17 at 20:05
  • @dnickless ah okay I misunderstood the _over and over again_ part. – Alex P. Nov 12 '17 at 20:07
  • I am using this for my application. Optimally, it will only have to run once, but I cannot get { unique: true } to work for my subdocument. That's why I want to remove all the matched elements. – earthyearth Nov 12 '17 at 20:08
  • @AlexP. would you happen to know how to remove all the elements both at position 0 and 2 without running it multiple times? – earthyearth Nov 12 '17 at 20:09
  • @earthyearth I would propose something similar that I suggested here. https://stackoverflow.com/questions/46603671/mongodb-string-to-date-conversion/46605995#46605995. You'd have to write a javascript function that removes the string from an array. And then the result of your function you would set in the update. And that I would execute for each document – Alex P. Nov 12 '17 at 20:12
  • @AlexP. ahh okay. I'll do that. – earthyearth Nov 12 '17 at 20:32
  • @AlexP. it says that my find is not a function and also if I do find() it will bring up all the documents right. I only need the one that has the `word` that I specify. – earthyearth Nov 12 '17 at 21:31