Store Polymorphic Data
On this page
Store polymorphic data when you need to access documents that have different fields or data types together in the same query.
MongoDB uses a flexible data model, which means documents in a single collection do not need to have the same structure. Polymorphic data is data in a single collection that varies in document fields or data types.
About this Task
In this example, your application stores professional athletes who play different sports. Your queries access all athletes, but the attributes stored for each athlete vary depending on their sport.
The polymorphic pattern stores different document shapes in the same collection, which improves performance for queries that need to access all athletes regardless of sport.
Steps
Insert the sample data
db.athletes.insertMany( [ { sport: "bowling", name: "Earl Anthony", career_earnings: 1440000, perfect_games: 25, pba_championships: 43, events: [ { name: "japan_pba", score: 300, year: 1972 } ] }, { sport: "tennis", name: "Steffi Graf", career_earnings: 21000000, grand_slam_wins: 22, surfaces: [ "grass", "clay", "hard court" ] }, { sport: "cricket", name: "Sachin Tendulkar", career_earnings: 8000000, runs: 15921, centuries: 51, teammates: [ "Arshad Ayub", "Kapil Dev" ] } ] )
Query all documents
Even though the documents in the athletes
collection have
different fields, you can return all documents with a single
query:
db.athletes.find()
Output:
[ { _id: ObjectId('6706dcd66fd2c3b24f2e7e92'), sport: 'bowling', name: 'Earl Anthony', career_earnings: 1440000, perfect_games: 25, pba_championships: 43, events: [ { name: 'japan_pba', score: 300, year: 1972 } ] }, { _id: ObjectId('6706dcd66fd2c3b24f2e7e93'), sport: 'tennis', name: 'Steffi Graf', career_earnings: 21000000, grand_slam_wins: 22, surfaces: [ 'grass', 'clay', 'hard court' ] }, { _id: ObjectId('6706dcd66fd2c3b24f2e7e94'), sport: 'cricket', name: 'Sachin Tendulkar', career_earnings: 8000000, runs: 15921, centuries: 51, teammates: [ 'Arshad Ayub', 'Kapil Dev' ] } ]
Query unique fields
The polymorphic pattern does not require additional logic to query on fields that are specific to a particular sport. For example, the following query returns athletes that have more than 20 grand slam wins, which only applies to athletes who play tennis:
db.athletes.find( { grand_slam_wins: { $gt: 20 } } )
Output:
[ { _id: ObjectId('6706cd8a6fd2c3b24f2e7e8d'), sport: 'tennis', name: 'Steffi Graf', career_earnings: 21000000, grand_slam_wins: 22, surfaces: [ 'grass', 'clay', 'hard court' ] } ]