Skip to content

Latest commit

 

History

History
208 lines (166 loc) · 6.07 KB

File metadata and controls

208 lines (166 loc) · 6.07 KB

This example shows how to use Apache Camel with Milvus as a vector database to perform similarity search on European cities based on geographic and demographic features.

OpenAI (via Ollama) is used to generate city data (country, latitude, longitude, population in millions) which is stored as a 3-dimensional feature vector in Milvus. A similarity search then finds cities with the most similar characteristics.

The pipeline works end-to-end:

  1. Insert: LLM returns raw city data (Rome: Italy;40.41;12.51;2.81) → VectorUtils normalizes to 0-1 range → stored in Milvus as 3D vector

  2. Search: LLM returns raw Rome coordinates → normalized → Milvus L2 similarity search → finds Rome, Milan, Zurich as the 3 closest cities

  3. Explain: The results are sent back to the LLM which provides a natural language explanation with approximate distances

Prerequisites

  1. A running Milvus instance (using Camel JBang):

camel infra run milvus
  1. A running Ollama instance with the required model:

ollama serve
ollama pull granite4:3b

How to run

You can run this example using:

mvn spring-boot:run

What happens

When the application starts, it executes the following pipeline:

  1. Create Collection - Creates a cities collection in Milvus with four fields: id (Int64 primary key), city (VarChar), country (VarChar), and features (3-dimensional FloatVector). The features vector encodes each city as [latitude, longitude, population_millions], normalized to 0-1 range. An IVF_FLAT index with L2 distance metric is created on the vector field.

  2. Insert Cities - Reads city names from input/cities.txt. For each city, it asks the LLM via openai:chat-completion to provide the country, latitude, longitude, and population (in millions). The response is parsed using Camel Simple expressions and normalized to a float vector via VectorUtils, then inserted into Milvus.

  3. Similarity Search - Searches for the 3 cities most similar to Rome based on L2 distance of their feature vectors. The search vector is also generated by the LLM.

  4. Explain - The search results are sent back to the LLM which provides a natural language explanation with approximate distances.

Expected output

Creating Milvus collection: cities
Collection created successfully
Index created successfully
Processing cities from: cities.txt
City data for Rome: Italy;41.90;12.50;2.87
Inserted Rome into Milvus
City data for Paris: France;48.86;2.35;2.16
Inserted Paris into Milvus
...
All cities indexed. Starting similarity search...
Searching for three closest cities to: Rome
Search vector for Rome: 41.90;12.50;2.87
Closest cities to Rome: [{rank=1, city=Rome, country=Italy}, {rank=2, city=Milan, country=Italy}, {rank=3, city=Zurich, country=Switzerland}].
Answer: Rome: 0 km, Milan: 200 km, Zurich: 400 km
Note
The exact similarity results may vary depending on the LLM responses.

Configuration

Edit src/main/resources/application.properties to configure:

  • camel.component.milvus.host - Milvus server host (default: localhost)

  • camel.component.milvus.port - Milvus gRPC port (default: 19530)

  • camel.component.openai.base-url - OpenAI-compatible API base URL (default: Ollama at http://localhost:11434/v1)

  • camel.component.openai.model - Chat completion model (default: granite4:3b)

To use OpenAI instead of Ollama, change the base URL and set your API key:

camel.component.openai.base-url=https://api.openai.com/v1
camel.component.openai.api-key=${OPENAI_API_KEY}
camel.component.openai.model=gpt-4o-mini

Trying out the example on OpenShift

First, start with creating a new OpenShift project:

$ oc new-project csb-example-milvus

Deploy a Milvus standalone instance:

$ cat << EOF| oc apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: milvus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: milvus
  template:
    metadata:
      labels:
        app: milvus
    spec:
      containers:
        - name: milvus
          image: milvusdb/milvus:latest
          command: ["milvus", "run", "standalone"]
          ports:
            - containerPort: 19530
            - containerPort: 9091
          env:
            - name: ETCD_USE_EMBED
              value: "true"
            - name: COMMON_STORAGETYPE
              value: local
---
apiVersion: v1
kind: Service
metadata:
  name: milvus
spec:
  selector:
    app: milvus
  ports:
    - name: grpc
      port: 19530
      targetPort: 19530
    - name: http
      port: 9091
      targetPort: 9091
EOF

Deploy an Ollama instance with the required model:

$ cat << EOF| oc apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ollama
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ollama
  template:
    metadata:
      labels:
        app: ollama
    spec:
      containers:
        - name: ollama
          image: ollama/ollama:latest
          ports:
            - containerPort: 11434
---
apiVersion: v1
kind: Service
metadata:
  name: ollama
spec:
  selector:
    app: ollama
  ports:
    - port: 11434
      targetPort: 11434
EOF

Wait for both pods to be ready, then pull the required model:

$ oc wait --for=condition=available deployment/milvus deployment/ollama --timeout=300s
$ oc exec deployment/ollama -- ollama pull granite4:3b

How to run

The application is deployed using the openshift-maven-plugin that takes care of creating all the necessary OpenShift resources.

Simply use the following command to deploy the application:

$ mvn clean package -Popenshift

After the application pod reaches the Ready state, you can try the same steps as in the local machine deployment.

To view the application logs, use oc logs deployment/csb-milvus

Help and contributions

If you hit any problem using Camel or have some feedback, then please let us know.

We also love contributors, so get involved :-)

The Camel riders!