概述
在这个快速教程中,我们将学习如何在MongoDB中使用Java的HashMap。MongoDB提供了一个对映友好的API,并且Spring Data MongoDB使处理映射或映射列表变得更加直观。
2. 设定场景
Spring Data MongoDB提供了MongoTemplate,它有许多重载的insert()
方法,允许我们向集合中插入一个映射。MongoDB以JSON格式表示文档,因此我们可以用Java中的Map<String, Object>
来复制它。
我们将使用MongoTemplate和一个简单的可重用映射来实现我们的用例。首先,创建映射引用并注入MongoTemplate:
class MongoDbHashMapIntegrationTest {
private static final Map<String, Object> MAP = new HashMap<>();
@Autowired
private MongoTemplate mongo;
}
然后,我们将初始化我们的映射,包含不同类型的几个条目:
@BeforeAll
static void init() {
MAP.put("name", "Document A");
MAP.put("number", 2);
MAP.put("dynamic", true);
}
我们用@BeforeAll标记它,以便所有测试都能使用。
3. 直接插入单个Map
首先,调用mongo.insert()
并选择要放入其中的集合:
@Test
void whenUsingMap_thenInsertSucceeds() {
Map<String, Object> saved = mongo.insert(MAP, "map-collection");
assertNotNull(saved.get("_id"));
}
无需特别的包装。插入后,我们的映射就成为集合中的一个单独的JSON文档。最重要的是,我们可以检查是否存在由MongoDB生成的 _id
属性,确保其已正确处理。*
4. 直接批量插入Map
s
我们还可以直接插入一个Map
的集合。每次插入都会成为一个不同的文档。此外,为了确保不插入重复项,我们将使用一个Set。
让我们将之前创建的映射和一个新的映射添加到我们的集合中:
@Test
void whenMapSet_thenInsertSucceeds() {
Set<Map<String, Object>> set = new HashSet<>();
Map<String, Object> otherMap = new HashMap<>();
otherMap.put("name", "Other Document");
otherMap.put("number", 22);
set.add(MAP);
set.add(otherMap);
Collection<Map<String, Object>> insert = mongo.insert(set, "map-set");
assertEquals(2, insert.size());
}
结果是两个插入。这种方法有助于减少一次性添加大量文档时的开销。
5. 从Map
构建Document
并插入
Document
类是Java中处理MongoDB文档的推荐方式。它实现了Map
和Bson
接口,使得操作变得简单。让我们使用接受映射的构造函数:
@Test
void givenMap_whenDocumentConstructed_thenInsertSucceeds() {
Document document = new Document(MAP);
Document saved = mongo.insert(document, "doc-collection");
assertNotNull(saved.get("_id"));
}
内部地,Document
使用LinkedHashMap
,保证了插入的顺序。
6. 从Map
构建BasicDBObject
并插入
虽然Document
类更受欢迎,但如果我们处理的是遗留代码,也可以从映射构建BasicDBObject
,因为Document
类从MongoDB驱动版本3开始才可用:
@Test
void givenMap_whenBasicDbObjectConstructed_thenInsertSucceeds() {
BasicDBObject dbObject = new BasicDBObject(MAP);
BasicDBObject saved = mongo.insert(dbObject, "db-collection");
assertNotNull(saved.get("_id"));
}
如果我们在处理旧代码,BasicDBObject
仍然很有帮助。
7. 从Object
值流构建Document
并插入
在最后一个示例中,我们将从一个Map
构建一个Document
对象,其中每个键的值是一个Object
值的列表。由于我们知道值的格式,我们可以根据值构建Document
,为每个值指定一个属性名称。
首先,让我们构建我们的input
映射:
Map<String, List<Object>> input = new HashMap<>();
List<Object> listOne = new ArrayList<>();
listOne.add("Doc A");
listOne.add(1);
List<Object> listTwo = new ArrayList<>();
listTwo.add("Doc B");
listTwo.add(2);
input.put("a", listOne);
input.put("b", listTwo);
如图所示,没有属性名称,只有值。因此,我们将流化input
的entrySet()
,并从中构建我们的result
。为此,我们将input
的每个条目收集到一个HashSet
中。然后,在累加器函数中,我们将每个条目的键作为_id
属性构建Document
。接着,我们遍历条目值,将它们放在适当的属性名称下。最后,我们将每个Document
添加到result
中:
Set<Document> result = input.entrySet()
.stream()
.collect(HashSet<Document>::new,
(set, entry) -> {
Document document = new Document();
document.put("_id", entry.getKey());
Iterator<Object> iterator = entry.getValue()
.iterator();
document.put("name", iterator.next());
document.put("number", iterator.next());
set.add(document);
},
Set::addAll
);
在这个例子中,我们不需要collect()
的第三个参数,因为只有并行流会使用组合函数。
最后,我们可以将result
插入到MongoDB中:
mongo.insert(result, "custom-set");
这种策略在将CSV值转换为JSON时非常有用。
8. 总结
在这篇文章中,我们了解了使用HashMap
和HashMap
列表向MongoDB集合中插入文档的不同方法。我们使用MongoTemplate简化了任务,并使用了最常见的文档抽象:BasicDBObject
和Document
。
如往常一样,源代码可以在GitHub上找到。