简体   繁体   中英

Get keys of fields from Embedded Array of Documents Mongodb Java

Here is a simplified schema of my MongoDB doc:

{
    "_id": 0,
    "config": [{
            "property1": "a",
            "property2": "b",
            "property3": "c",
            "property4": "d"
        },
        {
            "property1": "a",
            "property2": "bb",
            "property3": "cc",
            "property4": "d",
            "ispropert5": true
        },
        {
            "property1": "a",
            "property2": "b",
            "property3": "c",
            "property4": "ddd",
            "ispropert5": false,
            "ispropert6": false
        }
    ],
    "entity": "123asdf",
    "url": "",
    "createdDate": 1
}

As an output I need to get a list of unique keys of nested documents: {property1, property2, property3, property4, ispropert5, ispropert6}

I am trying this in my class but of course failing to cast ArrayList to Document:

 Document dbo = col.find().first();
        Set<String> keys = dbo.keySet();
        Iterator iterator = keys.iterator();

        while(iterator.hasNext()) {
            String key = iterator.next().toString();
            if(dbo.get(key) instanceof ArrayList){
                Document dboNested = (Document) dbo.get(key); //java.lang.ClassCastException: java.util.ArrayList cannot be cast to org.bson.Document
                Set<String> keysNested = dboNested.keySet();
                System.out.println("KeyNested: " + keysNested);
            }
        }

Like you've commented, on your code, you cannot convert ArrayList to Document, therefore you must cast it to an ArrayList like below:

 while(iterator.hasNext()) {
    String key = iterator.next().toString();
    Object value = dbo.get(key);
    if (value instanceof ArrayList){
        ArrayList<?> dboArrayNested = (ArrayList<?>) value;
        for (Object dboNestedObj : dboArrayNested) {
            if (dboNestedObj instanceof Document) {
                printKeysNested(Document.class.cast(dboNestedObj));
            }
        }
    // else if extra...
    } else if (value instanceof Document) {
        printKeysNested(Document.class.cast(value));
    }
}

public static void printKeysNested(Document dboNested) {
    Set<String> keysNested = dboNested.keySet();
    System.out.println("KeyNested: " + keysNested);
}

I hope this helps you.

I guess i am late here, but i was trying a more mongo way to do this. You would definitely want to execute this on a small set of query, may be a match stage before even starting this

db.coll.aggregate([{
            $unwind: '$config'
        }, {
            $project: {
                arr: {
                    $objectToArray: '$config'
                }
            }
        }, {
            $unwind: '$arr'
        }, {
            $group: {
                _id: {
                    key: '$arr.k'
                }
            }
        }, {
            $project: {
                key: '$_id.key',
                _id: 0
            }
        }
    ])

thanks to all the answers, here is the final code I have:

while (iterator.hasNext()) {
            String key = iterator.next().toString();
            Object value = dbo.get(key);
            if (value instanceof ArrayList) {
                ArrayList<?> dboArrayNested = (ArrayList<?>) value;
                for (Object dboNestedObj : dboArrayNested) {
                    Document dboNested = Document.class.cast(dboNestedObj);
                    if (dboNestedObj instanceof Document) {
                        keysNested.addAll(dboNested.keySet());
                    }
                }
                // else if extra...
            } else if (value instanceof Document) {
                Document dboNested = Document.class.cast(value);
                keysNested.addAll(dboNested.keySet());
            }
        }
        System.out.println("KeysNested: " + keysNested);

this outputs for the given example: [property1, property2, property3, property4, ispropert5, ispropert6]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM