Hello, @Jayaprakash_Nagappan!
The required result can be achieved mainly by using $objectToArray + $group stages.
Keep in mind, when using the examples below, that you may reach 16MB BSON document size limit, if there is a big variety of prop names or some prop names present in the most of documents in a huge collection.
For the example purpose, let’s simplify your documents structure to this:
db.test1.insertMany([
{ propA: 1 },
{ propA: '1', propB: true },
{ propA: 1, propC: [1, 2, 3] }
]);
Case 1: You need to get the list of unique names of properties of all documents in your collection.
Expected output:
{
"_id" : null,
"uniquePropNames" : [
"propB",
"propA",
"propC",
"_id"
]
}
Aggregation:
db.test1.aggregate([
{
$addFields: {
list: {
$objectToArray: '$$CURRENT',
}
}
},
{
$unwind: '$list',
},
{
$group: {
_id: null,
uniquePropNames: {
$addToSet: '$list.k'
},
}
}
]).pretty();
Case 2: You need to get the list of unique names of properties of all documents in your collection and each property should return unique list of types, it has throughout the documents per same collection - use this aggregation.
Expected output:
{ "propTypes" : [ "array" ], "propName" : "propC" }
{ "propTypes" : [ "bool" ], "propName" : "propB" }
{ "propTypes" : [ "string", "double" ], "propName" : "propA" }
Aggregation:
db.test1.aggregate([
{
$addFields: {
list: {
$objectToArray: '$$CURRENT',
}
}
},
{
$unwind: '$list',
},
{
$match: {
'list.k': {
$ne: '_id',
}
}
},
{
$group: {
_id: '$list.k',
propTypes: {
$addToSet: {
$type: '$list.v',
}
}
}
},
{
$project: {
_id: false,
propName: '$_id',
propTypes: true,
}
}
]).pretty();
Case 3: You need to get the list of unique names of properties of all documents in your collection and list Ids of documents, that have this prop.
Expected output:
{
"documentIdsThatHoldProp" : [
ObjectId("5f02435b9cb1606d755fd1e3")
],
"propName" : "propB"
}
{
"documentIdsThatHoldProp" : [
ObjectId("5f02435b9cb1606d755fd1e2"),
ObjectId("5f02435b9cb1606d755fd1e3"),
ObjectId("5f02435b9cb1606d755fd1e4")
],
"propName" : "propA"
}
{
"documentIdsThatHoldProp" : [
ObjectId("5f02435b9cb1606d755fd1e4")
],
"propName" : "propC"
}
Aggregation:
db.test1.aggregate([
{
$addFields: {
list: {
$objectToArray: '$$CURRENT',
}
}
},
{
$unwind: '$list',
},
{
$match: {
'list.k': {
$ne: '_id',
}
}
},
{
$group: {
_id: null,
uniquePropNames: {
$addToSet: {
name: '$list.k',
documentId: '$_id'
}
},
}
},
{
$unwind: '$uniquePropNames',
},
{
$group: {
_id: '$uniquePropNames.name',
documentIdsThatHoldProp: {
$push: '$uniquePropNames.documentId',
}
}
},
{
$project: {
_id: false,
propName: '$_id',
documentIdsThatHoldProp: true,
}
}
]).pretty();
Case4: You need to get the list of unique names of properties of all documents in your collection and list Ids all possible types, that each unique property can have, mapped to document ids, that hold property value of a given type.
Expected output:
{
"variations" : [
{
"propType" : "string",
"documentIds" : [
ObjectId("5f02435b9cb1606d755fd1e3")
]
},
{
"propType" : "double",
"documentIds" : [
ObjectId("5f02435b9cb1606d755fd1e2"),
ObjectId("5f02435b9cb1606d755fd1e4")
]
}
],
"propName" : "propA"
}
{
"variations" : [
{
"propType" : "array",
"documentIds" : [
ObjectId("5f02435b9cb1606d755fd1e4")
]
}
],
"propName" : "propC"
}
{
"variations" : [
{
"propType" : "bool",
"documentIds" : [
ObjectId("5f02435b9cb1606d755fd1e3")
]
}
],
"propName" : "propB"
}
Aggregation:
db.test1.aggregate([
{
$addFields: {
list: {
$objectToArray: '$$CURRENT',
}
}
},
{
$unwind: '$list',
},
{
$match: {
'list.k': {
$ne: '_id',
}
}
},
{
$group: {
_id: {
propName: '$list.k',
propType: {
$type: '$list.v',
}
},
documentIds: {
$push: '$_id',
}
}
},
{
$group: {
_id: '$_id.propName',
variations: {
$push: {
propType: '$_id.propType',
documentIds: '$documentIds'
}
}
}
},
{
$project: {
_id: false,
propName: '$_id',
variations: true,
}
}
]).pretty();