Skip to content

Yet another programming solutions log

Sample bits from programming for the future generations.

Technologies Technologies
  • Algorithms and Data Structures
  • Java Tutorials
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Spock Framework Tutorial
  • Spring Framework
  • Bash Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Developer’s Tools
  • Productivity
  • About
Expand Search Form

MongoDB 3 – filtering, sorting and projections

farenda 2016-04-01 1

Problem:

How to use MongoDb 3 API to filter, sort, and project data? Unlike previous versions of Mongo, the new version there provides convenient API to work with data.

In previous versions of MongoDB we had to create queries by putting together Document tree, which was very inconvenient. This approach still does work, but Mongo 3 shipped with bunch of flexible classes to make it a lot easier:

  • com.mongodb.client.model.Filters
  • com.mongodb.client.model.Projections
  • com.mongodb.client.model.Sorts

Solution:

In this example we’re going to explore the following data:

{"name": "TYH", "score": 962}
{"name": "QGV", "score": 814}
{"name": "WOJ", "score": 686}
{"name": "QES", "score": 600}
{"name": "VJU", "score": 590}
{"name": "LHZ", "score": 581}
{"name": "RHS", "score": 453}
{"name": "FPG", "score": 214}
{"name": "LUW", "score": 155}
{"name": "WOJ", "score": 25}

To import that in to MongoDB, put the data into a file (let’s say highscores.json) and import using the following command:

mongoimport -d test -c highscores < highscores.json

Now we can explore the data. In the following code we’re going to show how to use MongoDB 3 API to create filters, sort data, and select document fields (projections):

package com.farenda.mongodb;

import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Projections;
import com.mongodb.client.model.Sorts;
import org.bson.Document;
import org.bson.conversions.Bson;

import static java.lang.System.out;

public class FindProjectSortExample {

    private MongoConnector connector = new MongoConnector();
    private MongoCollection<Document> scores
            = connector.collection("highscores");

    public static void main(String[] args) {
        FindProjectSortExample example = new FindProjectSortExample();

        example.count();

        example.sortingExample();

        example.projectionExample();

        example.filteringUsingLogicalOperator();

        example.filteringUsingRegexp();

        example.compoundFiltering();
    }

    private void count() {
        out.println("Total number of scores: "
                     + scores.count());
    }

    private void sortingExample() {
        out.println("\nBest 3 by score:");
        FindIterable<Document> best3 = scores
                .find()
                .limit(3)
                .sort(Sorts.descending("score"));
        printResults(best3);
    }

    private void projectionExample() {
        out.println("\nThe best score:");
        FindIterable<Document> best = scores
                .find()
                .limit(1)
                .sort(Sorts.descending("score"))
                // "name" will be null in output
                .projection(Projections.include("score"));
        printResults(best);
    }

    private void filteringUsingLogicalOperator() {
        out.println("\nTake first where name is 'WOJ' or 'RHS':");
        Document doc = scores
                .find(Filters.or(
                        Filters.eq("name", "WOJ"),
                        Filters.eq("name", "RHS")))
                // Take only the first one:
                .first();
        if (doc != null) {
            out.printf("Name: %s, score: %d%n",
                    // Note the methods to remove casting:
                    doc.getString("name"),
                    doc.getInteger("score"));
        }
    }

    private void filteringUsingRegexp() {
        Bson nameRegexp = Filters.regex("name", "L");
        out.printf("\nScores matching 'L' regexp (%d):%n",
                scores.count(nameRegexp));
        printResults(scores.find(nameRegexp));
    }

    private void compoundFiltering() {
        out.println("\nTake scores >= 500, skip 2, limit to 5:");
        FindIterable<Document> results = scores
                .find()
                // Skip is third!
                .skip(2)
                // Limit is at the end!
                .limit(5)
                // Filtering goes second:
                .filter(Filters.gte("score", 500))
                // Sorting is done first!
                .sort(Sorts.orderBy(
                        Sorts.descending("score"),
                        Sorts.ascending("name")));
        printResults(results);
    }

    private void printResults(FindIterable<Document> results) {
        for (Document doc : results) {
            out.printf("Name: %s, score: %d%n",
                    doc.getString("name"),
                    doc.getInteger("score"));
        }
    }
}

In the code above we use MongoConnector, which can be easily constructed as in the previous post.

And here’s the output of running the above program:

Total number of scores: 10

Best 3 by score:
Name: TYH, score: 962
Name: QGV, score: 814
Name: WOJ, score: 686

The best score:
Name: null, score: 962

Take first where name is 'WOJ' or 'RHS':
Name: RHS, score: 453

Scores matching 'L' regexp (2):
Name: LHZ, score: 581
Name: LUW, score: 155

Take scores >= 500, skip 2, limit to 5:
Name: WOJ, score: 686
Name: QES, score: 600
Name: VJU, score: 590
Name: LHZ, score: 581

There are a few things to note:

  • The name in Best score in null, because in Projection we specified that we want only score field.
  • In logical operator example we display only one value, because we took only the first one from the result set.
  • The last example shows the order of operations: sort, filter, skip, and limit (from 6 scores above 500, 2 were skipped, so limit did nothing, because only 4 have left).
Share with the World!
Categories MongoDB Tags java, mongodb
Previous: MongoDB 3 – connect from Java
Next: Spring @Value default value

Recent Posts

  • Java 8 Date Time concepts
  • Maven dependency to local JAR
  • Caesar cipher in Java
  • Java casting trick
  • Java 8 flatMap practical example
  • Linked List – remove element
  • Linked List – insert element at position
  • Linked List add element at the end
  • Create Java Streams
  • Floyd Cycle detection in Java

Pages

  • About Farenda
  • Algorithms and Data Structures
  • Bash Tutorial
  • Bean Validation Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Java 8 Streams and Lambda Expressions Tutorial
  • Java Basics Tutorial
  • Java Collections Tutorial
  • Java Concurrency Tutorial
  • Java IO Tutorial
  • Java Tutorials
  • Java Util Tutorial
  • Java XML Tutorial
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Software Developer’s Tools
  • Spock Framework Tutorial
  • Spring Framework

Tags

algorithms bash bean-validation books clojure design-patterns embedmongo exercises git gof gradle groovy hateoas hsqldb i18n java java-basics java-collections java-concurrency java-io java-lang java-time java-util java-xml java8 java8-files junit linux lists log4j logging maven mongodb performance quartz refactoring regex rest slf4j solid spring spring-boot spring-core sql unit-tests

Yet another programming solutions log © 2021

sponsored