Aggregation pipeline with $lookup in Java

Hi,

In this topic, I’m answering a question I saw on Twitter:

https://twitter.com/nskarthik_k/status/1374614363709919233

Here is a short example of a $lookup with Java 4.2.2 (mongodb-driver-sync).

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import org.bson.json.JsonWriterSettings;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import static com.mongodb.client.model.Aggregates.lookup;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;

public class Lookup {

    public static void main(String[] args) {
        String connectionString = "mongodb://localhost";
        try (MongoClient mongoClient = MongoClients.create(connectionString)) {
            MongoDatabase db = mongoClient.getDatabase("test");
            MongoCollection<Document> books = db.getCollection("books");
            MongoCollection<Document> authors = db.getCollection("authors");
            books.drop();
            authors.drop();
            books.insertOne(new Document("_id", 1).append("title", "Super Book").append("authors", asList(1, 2)));
            authors.insertOne(new Document("_id", 1).append("name", "Bob"));
            authors.insertOne(new Document("_id", 2).append("name", "Alice"));

            Bson pipeline = lookup("authors", "authors", "_id", "authors");
            List<Document> booksJoined = books.aggregate(singletonList(pipeline)).into(new ArrayList<>());
            booksJoined.forEach(printDocuments());
        }
    }

    private static Consumer<Document> printDocuments() {
        return doc -> System.out.println(doc.toJson(JsonWriterSettings.builder().indent(true).build()));
    }
}

Here is the result I get in my console:

{
  "_id": 1,
  "title": "Super Book",
  "authors": [
    {
      "_id": 1,
      "name": "Bob"
    },
    {
      "_id": 2,
      "name": "Alice"
    }
  ]
}

As you can see, the authors IDs have been replaced by the actual documents from the authors collection.

I hope this help. I will be happy to answer your questions here if something isn’t clear in this example.

Cheers,
Maxime.

4 Likes

Thx sir
This sample Aggregation/lookup saved my time,
Appreciate u for sample code.

2 Likes

can u explain the three paramaters of the lookup function ?

$lookup is like this:

{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}

Or there is another alternative with a sub-pipeline like this:

db.orders.aggregate( [
   {
      $lookup:
         {
           from: "warehouses",
           let: { order_item: "$item", order_qty: "$ordered" },
           pipeline: [
              { $match:
                 { $expr:
                    { $and:
                       [
                         { $eq: [ "$stock_item",  "$$order_item" ] },
                         { $gte: [ "$instock", "$$order_qty" ] }
                       ]
                    }
                 }
              },
              { $project: { stock_item: 0, _id: 0 } }
           ],
           as: "stockdata"
         }
    }
] )

See the doc:

In my example above, I’m using the first version and my 4 parameters are matching the 4 parameters of the first version.

Here is the doc of what I’m using exactly:

Cheers,
Maxime.

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.