How to insert HashMap in MongoDB with Java?

1. Introduction

In this quick tutorial, we will learn how to work with Java hash map In MongoDB. MongoDB has a map-friendly API, and Spring Data makes working with MongoDB maps or lists of maps even easier.

2. Setting Up Our Scenario

Spring Data comes with MongoDB mongotemplatewhich has many overloaded versions insert() Which allows us to insert a map into our collection. MongoDB represents a document in JSON format. Therefore, we call it a. can repeat with Map<स्ट्रिंग, वस्तु> in java.

We will implement our own use cases mongotemplate And a simple reusable map. Let’s start by creating the map context and injecting mongotemplate,

class MongoDbHashMapIntegrationTest {
    private static final Map<String, Object> MAP = new HashMap<>();
    @Autowired
    private MongoTemplate mongo;
}

Then, we’ll start our map with a few entries, each of a different type:

@BeforeAll
static void init() {
    MAP.put("name", "Document A");
    MAP.put("number", 2);
    MAP.put("dynamic", true);
}

We are marking it with @BeforeAll so that all our tests can use it.

3. Single Insert Map straight

First, we call mongo.insert() and choose a collection to put it in:

@Test
void whenUsingMap_thenInsertSucceeds() {
    Map<String, Object> saved = mongo.insert(MAP, "map-collection");
    assertNotNull(saved.get("_id"));
}

No special cover is required. After insertion, our map becomes a single JSON document in our collection. Most importantly, we can check the presence of _identity The property that MongoDB generates ensures that it was processed correctly.

4. Insert Mapdirect in bulk

we can also put a collection of Maps. Each entry becomes a separate document. Also, to make sure we don’t insert duplicates, we’ll use a group.

Let’s add to our set the map we created earlier with a new one:

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

As a result, we get two inserts. This method helps in reducing the overhead of adding a lot of documents at once.

5. Construction document From Map enter more

document Classes are the recommended way to handle MongoDB documents in Java. it applies Map And bassonMakes it easier to work. Let’s use a constructor that accepts a map:

@Test
void givenMap_whenDocumentConstructed_thenInsertSucceeds() {
    Document document = new Document(MAP);
    Document saved = mongo.insert(document, "doc-collection");
    assertNotNull(saved.get("_id"));
}

internally, document a. uses it linked hash mapGuaranteed order of insertion.

6. Construction BasicDBObject From Map enter more

Although document class is preferred, we can even build a BasicDBObject From a map:

@Test
void givenMap_whenBasicDbObjectConstructed_thenInsertSucceeds() {
    BasicDBObject dbObject = new BasicDBObject(MAP);
    BasicDBObject saved = mongo.insert(dbObject, "db-collection");
    assertNotNull(saved.get("_id"));
}

BasicDBObject Still helpful if we’re working with legacy code, as document The class is only available from MongoDB driver version 3.

7. Build document from the stream of Thing value and insert

In our last example, we’ll build a document a. object from Map where the value of each key is a list of Thing value. Since we know the format of the values, we can construct our document By entering a property name for each value.

let’s start our build Input Map:

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

As we can see, there are no property names, only values. So, let’s stream our Input‘s EntrySet() and build us Result from this. To do this, we add each entry to our . will collect in Input In hashset, Then, we’ll build a document In the accumulator function, keep the entry key as _identity Property. After that, we’ll iterate over the entry values, placing them under the appropriate property name. Finally, we’ll add each document For us 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
  );

Let’s note that we don’t need the third argument from gather() in this instance. But this is because only parallel streams use the combiner function.

Finally, we can include Result In MongoDB:

mongo.insert(result, "custom-set");

For example, this strategy is useful if we want to convert CSV values ​​to JSON.

8. Conclusion

In this article, we have a . different ways of working with hash map and lists of hash mapTo insert documents into a MongoDB collection. we used mongotemplate To simplify the task and use the most common document abstract: BasicDBObject And document,

And as always, the source code is available on GitHub.

       

Leave a Comment