从文档嵌入式数组Mongodb Java获取字段的键

时间:2018-08-31 16:24:46

标签: java mongodb

这是我的MongoDB文档的简化架构:

{
    "_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
}

作为输出,我需要获取嵌套文档的唯一键的列表: {property1,property2,property3,property4,ispropert5,ispropert6}

我在课堂上尝试这样做,但是当然无法将ArrayList转换为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);
            }
        }

3 个答案:

答案 0 :(得分:0)

就像您评论的那样,您无法在代码上将ArrayList转换为Document,因此必须将其转换为如下所示的ArrayList:

 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);
}

希望对您有帮助。

答案 1 :(得分:0)

我想我来晚了,但是我正在尝试一种更蒙哥的方式来做到这一点。您肯定希望在一小部分查询上执行此操作,甚至可能是在match阶段才开始执行此操作

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

答案 2 :(得分:0)

感谢所有答案,这是我的最终代码:

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);

这将输出给定的示例: [property1,property2,property3,property4,ispropert5,ispropert6]