Semantic Search with LangChain4j and Infinispan

What You Will Learn

How to use Infinispan as a vector embedding store with LangChain4j to perform semantic similarity search over text.

Prerequisites

  • Java 17+

  • An Infinispan Server running on localhost:11222 (or Docker/Podman available for Testcontainers)

Start an Infinispan Server with Docker or Podman:

docker run -it --rm -p 11222:11222 -e USER=admin -e PASS=password quay.io/infinispan/server:latest
Tip
You can replace docker with podman in the command above if you use Podman.
Tip
If no server is running, the tutorial code automatically starts an Infinispan Server using Testcontainers.

Step 1: Add Dependencies

Add LangChain4j with the Infinispan embedding store and an ONNX embedding model:

<dependency>
   <groupId>dev.langchain4j</groupId>
   <artifactId>langchain4j-infinispan</artifactId>
</dependency>
<dependency>
   <groupId>dev.langchain4j</groupId>
   <artifactId>langchain4j-embeddings-all-minilm-l6-v2-q</artifactId>
</dependency>

The quantized MiniLM model runs locally. No API keys or external services needed.

Step 2: Initialize the Model and Create the Embedding Store

Create a local embedding model that converts text to vectors, then connect the embedding store to Infinispan:

   static void initEmbeddingModel() {
      embeddingModel = new AllMiniLmL6V2QuantizedEmbeddingModel();
      System.out.println("Embedding model initialized. Dimension: " + embeddingModel.dimension());
   }

   static void connectAndCreateStore() {
      ConfigurationBuilder builder = TutorialsConnectorHelper.connectionConfig();
      embeddingStore = InfinispanEmbeddingStore.builder()
            .cacheName("langchain4j-embeddings")
            .dimension(embeddingModel.dimension())
            .infinispanConfigBuilder(builder)
            .distance(3)
            .build();
      System.out.println("Connected to Infinispan and created embedding store.");
   }

Step 3: Store Text as Embeddings

Convert text segments to vectors and store them:

   static void addEmbedding(String text, Metadata metadata) {
      TextSegment segment = TextSegment.from(text, metadata);
      Embedding embedding = embeddingModel.embed(segment).content();
      embeddingStore.add(embedding, segment);
   }

Step 4: Search by Semantic Similarity

Query with natural language. The model finds semantically similar text, not just keyword matches:

      // Search by similarity
      String query = "How can I use Infinispan with AI?";
      System.out.println("Query: \"" + query + "\"");

      Embedding queryEmbedding = embeddingModel.embed(query).content();
      EmbeddingSearchRequest searchRequest = EmbeddingSearchRequest.builder()
            .queryEmbedding(queryEmbedding)
            .maxResults(3)
            .build();

      EmbeddingSearchResult<TextSegment> result = embeddingStore.search(searchRequest);
      List<EmbeddingMatch<TextSegment>> matches = result.matches();

      System.out.println("Found " + matches.size() + " results:");
      for (EmbeddingMatch<TextSegment> match : matches) {
         System.out.printf("  Score: %.4f | Text: %s%n",
               match.score(), match.embedded().text());
      }

Step 5: Run the Tutorial

mvn package exec:java

Results are ranked by cosine similarity score. Text about "vector search" and "embedding store" will rank highest for the AI query, even though the exact words differ.

What’s Next

  • Try vector search for direct vector API usage without LangChain4j