ikenas
ikenas

Reputation: 431

How to find all rows that have a subfield in nested records? PyMongo

All my records are structured like this:

{ 'name': 'John Doe',
  'atributes' : {
       'alive' : {'start':15816412115, 'end':1516186131 },
       'job'   : 'developer',
       'title' : 'senior',
   }
},
{ 'name': 'John Cena',
  'atributes-2017' : {
       'alive' : {'start':15816412115, 'end':1516186131 },
       'job'   : 'dancer',
   }
}

How select only the records that have a subfield title in atributes and atributes-2017:

I tried with this:

clients.find({'*': {'title': {'$exists': True }  }})

Upvotes: 0

Views: 36

Answers (1)

ngShravil.py
ngShravil.py

Reputation: 5048

Below query will be helpful:

db.collection.aggregate([
  {
    $group: {
      _id: null,
      docs: {
        $push: "$$ROOT"
      }
    }
  },
  {
    $project: {
      docs: {
        $map: {
          input: "$docs",
          as: "d",
          in: {
            $objectToArray: "$$d"
          }
        }
      }
    }
  },
  {
    $unwind: "$docs"
  },
  {
    $match: {
      "docs.v.title": {
        $exists: true
      }
    }
  },
  {
    $replaceRoot: {
      newRoot: {
        $arrayToObject: "$docs"
      }
    }
  }
])

MongoPlayGroundLink

My suggestion is, not to keep varying fields. You should keep same fields across all the documents and add extra information as the sub-fields (not in the field name). Like below:

{ 'name': 'John Doe',
  'atributes' : {
       'alive' : {'start':15816412115, 'end':1516186131 },
       'job'   : 'developer',
       'title' : 'senior',
   }
},
{ 'name': 'John Cena',
  'atributes' : {
       'alive' : {'start':15816412115, 'end':1516186131 },
       'job'   : 'dancer',
       'year'  : 2017
   }
}

Otherwise, it will become difficult to query.

Upvotes: 1

Related Questions