Explore Developer Center's New Chatbot! MongoDB AI Chatbot can be accessed at the top of your navigation to answer all your MongoDB questions.

Join us at AWS re:Invent 2024! Learn how to use MongoDB for AI use cases.
MongoDB Developer
MongoDB
plus
Sign in to follow topics
MongoDB Developer Centerchevron-right
Developer Topicschevron-right
Productschevron-right
MongoDBchevron-right

Why Unstructured Data is a Good Fit for Java

Aasawari Sahasrabuddhe7 min read • Published Aug 30, 2024 • Updated Sep 16, 2024
MongoDBJava
SNIPPET
Facebook Icontwitter iconlinkedin icon
Rate this article
star-empty
star-empty
star-empty
star-empty
star-empty
As Java developers of the legacy application you have worked on, most of you must have spent a large part of the application development mastering relational databases, building schemas, and perfecting SQL queries. During those days, the data was limited and was easily mapped to the strict schema structures. But with the changing era, where data is valued as gold, it is growing exponentially and getting more unstructured.
Unstructured data refers to information that does not follow a predefined pattern or is not organised in a strict pattern. As said above, the unstructured data mostly has data in varied formats like multimedia data, CSVs, and many more. Storage of these in relational databases has been difficult because of the diverse formats. Therefore, we store them as JSONs, XMLs, etc. Learn more about unstructured data.
Why should you care as a Java developer? The enterprise applications built today have more unstructured data like texts for customer reviews, product images, and shipping details, and these are all within a single platform. Relational databases require complex designs to handle this, while MongoDB thrives in this scenario, making it easier for Java developers to work with such diverse data types.

How does MongoDB prove to be helpful with unstructured data?

In today's fast-paced world of agile development, where application requirements are constantly evolving, the challenge of managing rapidly growing unstructured data becomes significantly more manageable. This is largely because unstructured data doesn’t need to conform to a rigid schema model, offering flexibility that is particularly beneficial when working with non-relational databases like MongoDB.
MongoDB's schemaless architecture allows developers to introduce new fields to documents or collections on the fly, without the need to overhaul an entire schema. This not only minimizes downtime but also speeds up the development process, enabling teams to adapt quickly to changing requirements.
In contrast, a strict schema model can demand substantial effort when continuous changes are required. By managing data in an unstructured format, MongoDB significantly reduces the overhead associated with these changes. Its dynamic schema is particularly well-suited for handling diverse data types such as images, tags, and metadata, making it an ideal choice for modern applications that handle a wide variety of content.
Moreover, MongoDB’s built-in horizontal scalability allows developers to effortlessly scale out their applications as data volumes increase, ensuring that performance remains consistent even as the amount of unstructured data grows. For Java developers, this means they can handle large datasets efficiently while maintaining the agility needed to meet evolving business needs.

How do you work with unstructured data in Java?

Now, let's get back to the main objective of the article: Why should you as a Java developer use MongoDB as the database for your growing unstructured data?
When we talk about unstructured data, it is mostly stored in the JSON format, and so is data stored in MongoDB. It stores the data in a JSON-like format known as BSON, or Binary JSON, which is highly compatible with Java’s POJO model.
This compatibility makes the mapping simpler. For example, let’s say you have a customer class in your Java application that stores details for a specific customer.
1public class Customer {
2 private String id;
3 private String name;
4 private String email;
5 // Constructors, getters, and setters
6}
With the MongoDB Java driver, you can map the Customer class to a MongoDB document. Below is the example, where this mapping would be useful in inserting a new document.
1public class CustomerRepository {
2 private MongoCollection<Document> collection;
3 public CustomerRepository() {
4 MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017");
5 this.collection = mongoClient.getDatabase("mydatabase").getCollection("customers");
6 }
7 public void addCustomer(Customer customer) {
8 Document doc = new Document("id", customer.getId())
9 .append("name", customer.getName())
10 .append("email", customer.getEmail());
11 collection.insertOne(doc);
12 }
13}
And similarly, querying and updating the data will become simpler. By using the MongoDB Java driver, you can work directly with BSON documents in a way that naturally fits Java’s POJO model.
The example above shows that MongoDB operations can be intuitive and simple even without using frameworks. Hence, this unstructured data is a good option for Java applications.
This mapping also proves to be helpful when operating on the subdocuments being created. For example, if the Customer also has details about their Orders it will be stored as:
1public class Customer {
2 private String id;
3 private String name;
4 private String email;
5 private List<String> Orders;
6 // Constructors, getters, and setters
7}
Here, to fetch the orders, you do not need to perform complicated joins on multiple tables. MongoDB allows you to retrieve nested or related data directly from a document. To do so, you could use:
1Customer customer = customerCollection.find(Filters.eq("_id", "customerId")).first();
2if (customer != null) {
3 List&<Order> orders = orderCollection.find(Filters.in("_id", customer.getOrders())).into(new ArrayList<>());
4 orders.forEach(order -> System.out.println(order.getProductName()));
5} else {
6 System.out.println("Customer not found");
7}
MongoDB’s aggregation framework also allows you to perform complex queries on large volumes of unstructured data. These operations are optimised and efficiently reduce the complex calculations of several joins.
MongoDB's Java driver provides builders to perform data manipulation and perform queries on the data. These builders simplify the process of creating complex MongoDB queries in Java by offering a clear, chainable API that resembles natural language, making the code easier to read and write.

Querying unstructured data in MongoDB with Java

In this section, we will provide practical examples of how MongoDB’s Java driver helps you work with unstructured data, while also discussing how to utilise POJOs and builders. There are certain prerequisites you need to follow along, including the necessary setup and knowledge required for working with MongoDB and Java.

Pre-requisites

  1. If you don’t already have an Atlas cluster, get started for free.
  2. Use the import mechanism to load the data given as productDetails.json into your Atlas cluster.
  3. Update your MongoDB Java driver to version 5.1 or above.
  4. Use Java version 17 or above.

How does unstructured data in MongoDB help in mapping POJOs?

Once you load the data into your Atlas cluster, your data should see the following structure, which is stored in BSON (Binary JSON) format:
1{
2 "_id": {"$oid": "66cc68309ff045b1b411b6ba"},
3 "productName": "Wireless Mouse",
4 "category": "Electronics",
5 "price": 29.99,
6 "stock": 150,
7 "description": "Ergonomic wireless mouse with adjustable DPI settings.",
8 "brand": "TechBrand",
9 "images": [
10 {
11 "url": "https://example.com/images/wireless_mouse_1.jpg",
12 "altText": "Wireless Mouse Top View"
13 },
14 {
15 "url": "https://example.com/images/wireless_mouse_2.jpg",
16 "altText": "Wireless Mouse Side View"
17 }
18 ],
19 "features": "2.4 GHz wireless connectivity, Adjustable DPI from 800 to 1600, Compatible with Windows and macOS",
20 "reviews": [
21 {
22 "customerId": {"$oid": "66cc67443921db64869bcf3d"},
23 "rating": 4.5,
24 "comment": "Great mouse, very comfortable to use!",
25 "date": "2023-03-01T08:45:00Z"
26 }
27 ]
28}
Since MongoDB stores data in a JSON-like format, POJOs are particularly useful. They align closely with MongoDB's document-oriented data model, allowing for a more natural and efficient development process.
For our example, we have a POJOs class created for Product, Image, and Reviews using model classes as Product.java, Image.java, and Reviews.java class respectively.
Having the fields mapped inside the POJOs makes the operations on this easy and efficient.
For example, in Main.java, the basic CRUD operations become simpler.
In the code below, we first try to make the connection with the MongoDB Atlas URI by placing the connection string in the environment variable. You can follow the documentation to get your connection string.
In the last part of the code, we perform some simple operations, like CRUD (Create, Read, Update, Delete), to operate on the database.
The complete code is given as:
1public static void main(String[] args) {
2 ConnectionString connectionString = new ConnectionString(System.getenv("mongodb.uri"));
3 CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build());
4 CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry);
5 MongoClientSettings clientSettings = MongoClientSettings.builder()
6 .applyConnectionString(connectionString)
7 .codecRegistry(codecRegistry)
8 .build();
9 try (MongoClient mongoClient = MongoClients.create(clientSettings)) {
10 MongoDatabase database = mongoClient.getDatabase("ecommerce");
11 MongoCollection<Product> collection = database.getCollection("productDetails", Product.class);
12
13 Product newProduct = new Product();
14 newProduct.setId(new ObjectId());
15 newProduct.setProductName("Wireless Mouse");
16 newProduct.setCategory("Electronics");
17 newProduct.setPrice(29.99);
18 newProduct.setStock(150);
19 newProduct.setDescription("Ergonomic wireless mouse with adjustable DPI settings.");
20 newProduct.setBrand("TechBrand");
21 newProduct.setFeatures("2.4 GHz wireless connectivity, Adjustable DPI from 800 to 1600, Compatible with Windows and macOS");
22
23 List<Image> images = new ArrayList<>();
24 images.add(new Image("https://example.com/images/wireless_mouse_1.jpg", "Wireless Mouse Top View"));
25 images.add(new Image("https://example.com/images/wireless_mouse_2.jpg", "Wireless Mouse Side View"));
26 newProduct.setImages(images);
27
28 List<Reviews> reviews = new ArrayList<>();
29 reviews.add(new Reviews(new ObjectId("66cc67443921db64869bcf3d"), 4.5, "Great mouse, very comfortable to use!", "2024-08-18T19:00:00Z"));
30 newProduct.setReviews(reviews);
31
32 collection.insertOne(newProduct);
33 System.out.println("Inserted product: " + newProduct);
34
35 Product foundProduct = collection.find(Filters.eq("productName", "Wireless Mouse")).first();
36 System.out.println("Found product: " + foundProduct);
37
38 collection.updateOne(Filters.eq("_id", newProduct.getId()), Updates.set("stock", 140));
39 Product updatedProduct = collection.find(Filters.eq("_id", newProduct.getId())).first();
40 System.out.println("Updated product stock: " + updatedProduct.getStock());
41
42 collection.deleteOne(Filters.eq("_id", newProduct.getId()));
43 System.out.println("Deleted product: " + newProduct.getProductName());
44 }
45}

Using Builders in MongoDB

Builders, provided by the MongoDB Java driver, simplify the operations for basic CRUD and also for writing complex aggregations. These are the utility classes which allow you to create complex operations in a readable and type-safe manner, making the code more expressive and easier to maintain.
Let us understand the usage of builders through a code example.
Aggregation builders are built using the aggregate class which provides the method to create pipeline stages in the Java code.
The example given below from the AggregationBuilder.java class shows how you can create a simple aggregation pipeline using builder methods.
The below aggregation is an instance to show product details for the top three highest-reviewed products.
1private static void runAverageRatingPipeline(MongoCollection<Product> collection) {
2 AggregateIterable<Product> result = collection.aggregate(Arrays.asList(
3 unwind("$reviews"),
4 group("$_id",
5 avg("averageRating", "$reviews.rating"),
6 first("productName", "$productName"),
7 first("category", "$category"),
8 first("price", "$price"),
9 first("brand", "$brand"),
10 first("stock", "$stock")
11 ),
12 match(gte("averageRating", 4.5)),
13 sort(Sorts.descending("averageRating")),
14 project(fields(
15 excludeId(),
16 include("productName", "category", "price", "brand", "stock")
17 )),
18 limit(3)
19 )
20 );
21
22 System.out.println("High-Rated Products:");
23 for (Product doc : result) {
24 System.out.println(doc.toProductDetails());
25 }
26}
Similarly, the code snippet below uses update builders to update the collection records.
1private static void updateLowStockProducts(MongoCollection<Product> collection) {
2 collection.updateMany(
3 lt("stock", 50),
4 Updates.inc("stock", 20)
5 );
6
7 System.out.println("Update: Increased stock for products with less than 50 units.");
8}
This is how builders make your life simpler and more efficient. You can visit the complete code in the GitHub repository.

Conclusion

To sum it all up, the truth is data is growing at an unprecedented rate and becoming increasingly diverse and unstructured, and traditional relational databases might need to be revised. For Java developers accustomed to the rigidity of SQL schemas, MongoDB offers a refreshing alternative with its schemaless architecture and natural integration with Java's POJO model.
Moreover, MongoDB’s dynamic schema and powerful aggregation framework allow for agile development and complex querying without the overhead of rigid schemas.
Incorporating MongoDB into your Java applications not only streamlines data management but also empowers you to adapt swiftly to changing requirements and scale with ease. As the data landscape evolves, MongoDB's capabilities position you to deal with the challenges of unstructured data and ensure your applications remain robust and responsive in a data-driven world.
If you wish to learn more about building applications in Java and frameworks like Spring Boot and Quarkus, visit the MongoDB Developer Center for more interesting tutorials.
Top Comments in Forums
There are no comments on this article yet.
Start the Conversation

Facebook Icontwitter iconlinkedin icon
Rate this article
star-empty
star-empty
star-empty
star-empty
star-empty
Related
Quickstart

Basic MongoDB Operations in Python


Sep 23, 2022 | 11 min read
Tutorial

How to Maintain Multiple Versions of a Record in MongoDB (2024 Updates)


Aug 12, 2024 | 6 min read
Quickstart

Introduction to MongoDB and Helidon


Nov 12, 2024 | 6 min read
Quickstart

Java - Change Streams


Oct 01, 2024 | 10 min read
Table of Contents