2

I'm stuck at the situation when the type of an object was changed.

How can I convert this:

{ 
"_id" : NumberLong(257),
"address" : "street  Street, house 50, appartment 508, floor 5"
}

to this:

{ 
"_id" : NumberLong(257),
 "userAddressList" : [{
        "street" : "Street",
        "house" : "50",
        "building" : "",
        "appartment " : NumberLong(508),
        "entrance" : NumberLong(0),
        "floor" : NumberLong(5),
        "intercom" : ""
    }]
}

using mongo shell?

I need to convert about 350 entries, hope it can be done by the script.

2 Answers 2

6

You could try this:

db.collection.find().forEach( function (x) {   
    lines = x.address.split(",");
    obj = {};
    userAddressList = [];
    lines.forEach( function (address){
        addressArray = address.replace(/^\s\s*/, '').replace(/\s\s*$/, '').split(" ");
        obj[addressArray[0]] = !isNaN(parseInt(addressArray[1])) ? parseInt(addressArray[1]) : addressArray[1];        
    });
    obj.building = "";
    obj.intercom = "";
    userAddressList.push(obj);
    x.userAddressList = userAddressList; // convert field to string
    db.collection.save(x);
});

You can also use the MongoDB aggregation framework to convert the given document into the desired format. You'll want to use the $addFields, $regexFind, and $convert operators to extract, transform, and load the new fields.

The following aggregation pipeline should give you the desired results:

db.collection.aggregate([
  { $addFields: {
      userAddressList: {
        $let: {
          vars: {
            street: {
              $regexFind: { input: "$address", regex: /(\w+)\s+Street/ }
            },
            house: {
              $regexFind: { input: "$address", regex: /house\s+(\d+)/ }
            },
            appartment: {
              $regexFind: { input: "$address", regex: /appartment\s+(\d+)/ }
            },
            floor: {
              $regexFind: { input: "$address", regex: /floor\s+(\d+)/ }
            }
          },
          in: [
            {
              street: "$$street.match",
              house: "$$house.match",
              building: "",
              appartment: {
                $convert: {
                  input: "$$appartment.match",
                  to: "long",
                  onError: NumberLong(0),
                }
              },
              entrance: NumberLong(0),
              floor: {
                $convert: {
                  input: "$$floor.match",
                  to: "long",
                  onError: NumberLong(0)
                }
              },
              intercom: ""
            }
          ]
        }
      }
    } },
    { $project: { address: 0 } }
]);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! Worked for me! Can't upvote your comment due to lack of my reputation, but will do it after I gain enough of it. Thanks again! You were very helpful!
1

you can use a foreach in the update like this

db.test.find( { } ).forEach( function (x) {
x.userAddressList = x.address.split(" "); db.test.save(x); });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.