2

How can I getthe data that has email as abc@gmail.com in mongoDB?I don't know the Key Name and I want to iterate through all the data.

I have data like this:

{
    "_id":"5c0a1589a5a41b2ae707317b",
    "test1":{
        "email":"abc@gmail.com",
        "phoneNo":"123456897",
        "endpointId":"test1"
    }
}

{
    "_id":"5c0a1989a5a41b2ae807317b",
    "test2":{
        "email":"abc@gmail.com",
        "phoneNo":"123456897",
        "endpointId":"test2"
    }
}

{
    "_id":"5c0a1989a5a41b2ae807317b",
    "test2":{
        "email":"pqr@gmail.com",
        "phoneNo":"123456897",
        "endpointId":"test3"
    }
}

But the object key is not known at the time of searching. I want to iterate through all the data and get matched data that has specific email.

If I know the key name like test1,test2 etc then I can use find({test1:{...}}) but Here I don't know the key value.

So, how can I do that?

Ashh
  • 44,693
  • 14
  • 105
  • 132
Harsh Patel
  • 6,334
  • 10
  • 40
  • 73

3 Answers3

1

You can use below aggregation using $objectToArray in mongodb 3.4 and above

db.collection.aggregate([
  { "$addFields": {
    "field": { "$objectToArray": "$$ROOT" }
  }},
  { "$match": { "field.v.email": "abc@gmail.com" }},
  { "$project": { "field": 0 }}
])
Ashh
  • 44,693
  • 14
  • 105
  • 132
0

I am assuming you get the objects in array type.

I made a method named findObject. This method will take the object array and the desired email.

Finally, return the first object, that matched with the email.

const data = [{
    "_id":"5c0a1589a5a41b2ae707317b",
    "test1":{
        "email": "abc@gmail.com",
        "phoneNo": "123456897",
        "endpointId":"test1"
    }
},
{
    "_id":"5c0a1989a5a41b2ae807317b",
    "test2":{
        "email": "abc@gmail.com",
        "phoneNo": "123456897",
        "endpointId":"test2"
    }
},
{
    "_id":"5c0a1989a5a41b2ae807317b",
    "test2":{
        "email": "pqr@gmail.com",
        "phoneNo": "123456897",
        "endpointId": "test3"
    }
}];

const findObject = (data, email) => {
    for (let index=0; index<data.length; index++) {
        const currentData = data[index];
        for (let property in currentData) {
            if (property != '_id' && currentData[property].email == email) {
                return currentData;
            }
        }
    }
    return null;
}

let desiredObject;
const desiredEmail = 'abc@gmail.com';

desiredObject = findObject(data, desiredEmail);

console.log(desiredObject);

And the output will be

{ _id: '5c0a1589a5a41b2ae707317b',
  test1:
   { email: 'abc@gmail.com',
     phoneNo: '123456897',
     endpointId: 'test1' } }
Shams Nahid
  • 6,239
  • 8
  • 28
  • 39
0

I think you can't do query on totally unknown field! if you could change your schema see here for more info, also you could write script to migrate to a new DB with new schema:

// new doc instance
{
    "_id":"5c0a1589a5a41b2ae707317b",
    "obj": {
        "name": "test1"
        "email":"abc@gmail.com"
        "phoneNo":"123456897",
        "endpointId":"test1"
    }
},
{
    "_id":"5c0a1989a5a41b2ae807317b",
    "obj": {
        "name": "test2"
        "email":"abc@gmail.com"
        "phoneNo":"123456897",
        "endpointId":"test2"
    }
},
{
    "_id":"5c0a1989a5a41b2ae807317b",
    "obj": {
        "name": "test3"
        "email":"pqr@gmail.com"
        "phoneNo":"123456897",
        "endpointId":"test3"
    }
}

otherwise, check this may works correctly. if all of them is not effective so make a query to get all of your data as an Array and use filter method on it:

Model.find({}, (err, docs) => {
    const result = docs.filter((doc) => {
         for (key in doc) {
              if (doc[key].email === 'abc@gmail.com')
                   return doc;
         }
    });
    console.log(result);
});
eerFun
  • 145
  • 8