Java+;MongoDB:如何使用完整路径获取嵌套字段值?
我有一个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)
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。