Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java+;MongoDB:如何使用完整路径获取嵌套字段值?_Java_Mongodb_Mongodb Java - Fatal编程技术网

Java+;MongoDB:如何使用完整路径获取嵌套字段值?

Java+;MongoDB:如何使用完整路径获取嵌套字段值?,java,mongodb,mongodb-java,Java,Mongodb,Mongodb Java,我有一个MongoDB字段main.internal.leaf的路径,但每个字段都不存在 我应该用Java编写,避免null: String leaf = ""; if (document.get("main") != null && document.get("main", Document.class).get("inner") != null) { leaf = document.get("main", Document.class)

我有一个MongoDB字段
main.internal.leaf
的路径,但每个字段都不存在

我应该用Java编写,避免
null

String leaf = "";
if (document.get("main") != null && 
        document.get("main", Document.class).get("inner") != null) {
    leaf = document.get("main", Document.class)
        .get("inner", Document.class).getString("leaf");
}
在这个简单的示例中,我只设置了3个级别:
main
internal
leaf
,但我的文档更深入

那么有没有办法避免我写这些
null
检查

像这样:

String leaf = document.getString("main.inner.leaf", "");
// "" is the deafult value if one of the levels doesn't exist
或使用第三方库:

String leaf = DocumentUtils.getNullCheck("main.inner.leaf", "", document);

非常感谢。

因为中间属性是可选的,所以您必须以空安全的方式访问叶值

你可以自己用这样的方法来做

if (document.containsKey("main")) {
    Document _main  = document.get("main", Document.class);
    if (_main.containsKey("inner")) {
        Document _inner = _main.get("inner", Document.class);
        if (_inner.containsKey("leaf")) {
            leafValue = _inner.getString("leaf");
        }
    }
}
注意:这可以封装在一个实用程序中,以使其更加用户友好

或者使用第三方库,例如

但是,您无法避免空安全检查,因为文档结构使得中间级别可能为空。您所能做的就是减轻处理空安全性的负担

下面是一个示例测试用例,展示了这两种方法:

@Test
public void readNestedDocumentsWithNullSafety() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
    Document inner = new Document("leaf", "leafValue");
    Document main = new Document("inner", inner);
    Document fullyPopulatedDoc = new Document("main", main);

    assertThat(extractLeafValueManually(fullyPopulatedDoc), is("leafValue"));
    assertThat(extractLeafValueUsingThirdPartyLibrary(fullyPopulatedDoc, "main.inner.leaf", ""), is("leafValue"));


    Document emptyPopulatedDoc = new Document();
    assertThat(extractLeafValueManually(emptyPopulatedDoc), is(""));
    assertThat(extractLeafValueUsingThirdPartyLibrary(emptyPopulatedDoc, "main.inner.leaf", ""), is(""));

    Document emptyInner = new Document();
    Document partiallyPopulatedMain = new Document("inner", emptyInner);
    Document partiallyPopulatedDoc = new Document("main", partiallyPopulatedMain);

    assertThat(extractLeafValueManually(partiallyPopulatedDoc), is(""));
    assertThat(extractLeafValueUsingThirdPartyLibrary(partiallyPopulatedDoc, "main.inner.leaf", ""), is(""));
}

private String extractLeafValueUsingThirdPartyLibrary(Document document, String path, String defaultValue) {
    try {
        Object value = PropertyUtils.getNestedProperty(document, path);
        return value == null ? defaultValue : value.toString();
    } catch (Exception ex) {
        return defaultValue;
    }
}

private String extractLeafValueManually(Document document) {
    Document inner = getOrDefault(getOrDefault(document, "main"), "inner");
    return inner.get("leaf", "");
}

private Document getOrDefault(Document document, String key) {
    if (document.containsKey(key)) {
        return document.get(key, Document.class);
    } else {
        return new Document();
    }
}

我想避免写空检查,我知道它们是必要的。我发布的问题是:是否有第三个库为我实现空检查?我的回答提供了两种方法:编写自己的空检查或使用第三方库。请看一看方法:
使用第三方库提取LeafValues
,该库使用的是
PropertyUtils.getNestedProperty()
from。