Programming for fun and profit

Programming tutorials, problems, solutions. Always with code.

MongoDB 3 – filtering, sorting and projections


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


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







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

    private void sortingExample() {
        out.println("\nBest 3 by score:");
        FindIterable<Document> best3 = scores

    private void projectionExample() {
        out.println("\nThe best score:");
        FindIterable<Document> best = scores
                // "name" will be null in output

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

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

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

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

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!