How to Get Started with Solvio Locally

In this short example, you will use the Python Client to create a Collection, load data into it and run a basic search query.

Download and run

First, download the latest Solvio image from Dockerhub:

docker pull solvio/solvio

Then, run the service:

docker run -p 6333:6333 -p 6334:6334 \
    -v "$(pwd)/solvio_storage:/solvio/storage:z" \
    solvio/solvio

Under the default configuration all data will be stored in the ./solvio_storage directory. This will also be the only directory that both the Container and the host machine can both see.

Solvio is now accessible:

Initialize the client

from solvio_client import SolvioClient

client = SolvioClient(url="http://localhost:6333")
import { SolvioClient } from "@solvio/js-client-rest";

const client = new SolvioClient({ host: "localhost", port: 6333 });
use solvio_client::Solvio;

// The Rust client uses Solvio's gRPC interface
let client = Solvio::from_url("http://localhost:6334").build()?;
import io.solvio.client.SolvioClient;
import io.solvio.client.SolvioGrpcClient;

// The Java client uses Solvio's gRPC interface
SolvioClient client = new SolvioClient(
    SolvioGrpcClient.newBuilder("localhost", 6334, false).build());
using Solvio.Client;

// The C# client uses Solvio's gRPC interface
var client = new SolvioClient("localhost", 6334);
import "github.com/solvio/go-client/solvio"

// The Go client uses Solvio's gRPC interface
client, err := solvio.NewClient(&solvio.Config{
	Host: "localhost",
	Port: 6334,
})

Create a collection

You will be storing all of your vector data in a Solvio collection. Let’s call it test_collection. This collection will be using a dot product distance metric to compare vectors.

from solvio_client.models import Distance, VectorParams

client.create_collection(
    collection_name="test_collection",
    vectors_config=VectorParams(size=4, distance=Distance.DOT),
)
await client.createCollection("test_collection", {
  vectors: { size: 4, distance: "Dot" },
});
use solvio_client::solvio::{CreateCollectionBuilder, VectorParamsBuilder};

client
    .create_collection(
        CreateCollectionBuilder::new("test_collection")
            .vectors_config(VectorParamsBuilder::new(4, Distance::Dot)),
    )
    .await?;
import io.solvio.client.grpc.Collections.Distance;
import io.solvio.client.grpc.Collections.VectorParams;

client.createCollectionAsync("test_collection",
        VectorParams.newBuilder().setDistance(Distance.Dot).setSize(4).build()).get();
using Solvio.Client.Grpc;

await client.CreateCollectionAsync(collectionName: "test_collection", vectorsConfig: new VectorParams
{
    Size = 4, Distance = Distance.Dot
});
import (
	"context"

	"github.com/solvio/go-client/solvio"
)

client.CreateCollection(context.Background(), &solvio.CreateCollection{
	CollectionName: "{collection_name}",
	VectorsConfig: solvio.NewVectorsConfig(&solvio.VectorParams{
		Size:     4,
		Distance: solvio.Distance_Cosine,
	}),
})

Add vectors

Let’s now add a few vectors with a payload. Payloads are other data you want to associate with the vector:

from solvio_client.models import PointStruct

operation_info = client.upsert(
    collection_name="test_collection",
    wait=True,
    points=[
        PointStruct(id=1, vector=[0.05, 0.61, 0.76, 0.74], payload={"city": "Berlin"}),
        PointStruct(id=2, vector=[0.19, 0.81, 0.75, 0.11], payload={"city": "London"}),
        PointStruct(id=3, vector=[0.36, 0.55, 0.47, 0.94], payload={"city": "Moscow"}),
        PointStruct(id=4, vector=[0.18, 0.01, 0.85, 0.80], payload={"city": "New York"}),
        PointStruct(id=5, vector=[0.24, 0.18, 0.22, 0.44], payload={"city": "Beijing"}),
        PointStruct(id=6, vector=[0.35, 0.08, 0.11, 0.44], payload={"city": "Mumbai"}),
    ],
)

print(operation_info)
const operationInfo = await client.upsert("test_collection", {
  wait: true,
  points: [
    { id: 1, vector: [0.05, 0.61, 0.76, 0.74], payload: { city: "Berlin" } },
    { id: 2, vector: [0.19, 0.81, 0.75, 0.11], payload: { city: "London" } },
    { id: 3, vector: [0.36, 0.55, 0.47, 0.94], payload: { city: "Moscow" } },
    { id: 4, vector: [0.18, 0.01, 0.85, 0.80], payload: { city: "New York" } },
    { id: 5, vector: [0.24, 0.18, 0.22, 0.44], payload: { city: "Beijing" } },
    { id: 6, vector: [0.35, 0.08, 0.11, 0.44], payload: { city: "Mumbai" } },
  ],
});

console.debug(operationInfo);
use solvio_client::solvio::{PointStruct, UpsertPointsBuilder};

let points = vec![
    PointStruct::new(1, vec![0.05, 0.61, 0.76, 0.74], [("city", "Berlin".into())]),
    PointStruct::new(2, vec![0.19, 0.81, 0.75, 0.11], [("city", "London".into())]),
    PointStruct::new(3, vec![0.36, 0.55, 0.47, 0.94], [("city", "Moscow".into())]),
    // ..truncated
];

let response = client
    .upsert_points(UpsertPointsBuilder::new("test_collection", points).wait(true))
    .await?;

dbg!(response);
import java.util.List;
import java.util.Map;

import static io.solvio.client.PointIdFactory.id;
import static io.solvio.client.ValueFactory.value;
import static io.solvio.client.VectorsFactory.vectors;

import io.solvio.client.grpc.Points.PointStruct;
import io.solvio.client.grpc.Points.UpdateResult;

UpdateResult operationInfo =
    client
        .upsertAsync(
            "test_collection",
            List.of(
                PointStruct.newBuilder()
                    .setId(id(1))
                    .setVectors(vectors(0.05f, 0.61f, 0.76f, 0.74f))
                    .putAllPayload(Map.of("city", value("Berlin")))
                    .build(),
                PointStruct.newBuilder()
                    .setId(id(2))
                    .setVectors(vectors(0.19f, 0.81f, 0.75f, 0.11f))
                    .putAllPayload(Map.of("city", value("London")))
                    .build(),
                PointStruct.newBuilder()
                    .setId(id(3))
                    .setVectors(vectors(0.36f, 0.55f, 0.47f, 0.94f))
                    .putAllPayload(Map.of("city", value("Moscow")))
                    .build()))
                // Truncated
            .get();

System.out.println(operationInfo);
using Solvio.Client.Grpc;

var operationInfo = await client.UpsertAsync(collectionName: "test_collection", points: new List<PointStruct>
{
    new()
    {
        Id = 1,
            Vectors = new float[]
            {
                0.05f, 0.61f, 0.76f, 0.74f
            },
            Payload = {
                ["city"] = "Berlin"
            }
    },
    new()
    {
        Id = 2,
            Vectors = new float[]
            {
                0.19f, 0.81f, 0.75f, 0.11f
            },
            Payload = {
                ["city"] = "London"
            }
    },
    new()
    {
        Id = 3,
            Vectors = new float[]
            {
                0.36f, 0.55f, 0.47f, 0.94f
            },
            Payload = {
                ["city"] = "Moscow"
            }
    },
    // Truncated
});

Console.WriteLine(operationInfo);
import (
	"context"
	"fmt"

	"github.com/solvio/go-client/solvio"
)

operationInfo, err := client.Upsert(context.Background(), &solvio.UpsertPoints{
	CollectionName: "test_collection",
	Points: []*solvio.PointStruct{
		{
			Id:      solvio.NewIDNum(1),
			Vectors: solvio.NewVectors(0.05, 0.61, 0.76, 0.74),
			Payload: solvio.NewValueMap(map[string]any{"city": "Berlin"}),
		},
		{
			Id:      solvio.NewIDNum(2),
			Vectors: solvio.NewVectors(0.19, 0.81, 0.75, 0.11),
			Payload: solvio.NewValueMap(map[string]any{"city": "London"}),
		},
		{
			Id:      solvio.NewIDNum(3),
			Vectors: solvio.NewVectors(0.36, 0.55, 0.47, 0.94),
			Payload: solvio.NewValueMap(map[string]any{"city": "Moscow"}),
		},
        // Truncated
	},
})
if err != nil {
	panic(err)
}
fmt.Println(operationInfo)

Response:

operation_id=0 status=<UpdateStatus.COMPLETED: 'completed'>
{ operation_id: 0, status: 'completed' }
PointsOperationResponse {
    result: Some(
        UpdateResult {
            operation_id: Some(
                0,
            ),
            status: Completed,
        },
    ),
    time: 0.00094027,
}
operation_id: 0
status: Completed
{ "operationId": "0", "status": "Completed" }
operation_id:0  status:Acknowledged

Run a query

Let’s ask a basic question - Which of our stored vectors are most similar to the query vector [0.2, 0.1, 0.9, 0.7]?

search_result = client.query_points(
    collection_name="test_collection",
    query=[0.2, 0.1, 0.9, 0.7],
    with_payload=False,
    limit=3
).points

print(search_result)
let searchResult = await client.query(
    "test_collection", {
    query: [0.2, 0.1, 0.9, 0.7],
    limit: 3
});

console.debug(searchResult.points);
use solvio_client::solvio::QueryPointsBuilder;

let search_result = client
    .query(
        QueryPointsBuilder::new("test_collection")
            .query(vec![0.2, 0.1, 0.9, 0.7])
    )
    .await?;

dbg!(search_result);
import java.util.List;

import io.solvio.client.grpc.Points.ScoredPoint;
import io.solvio.client.grpc.Points.QueryPoints;

import static io.solvio.client.QueryFactory.nearest;

List<ScoredPoint> searchResult =
    client.queryAsync(QueryPoints.newBuilder()
                .setCollectionName("test_collection")
                .setLimit(3)
                .setQuery(nearest(0.2f, 0.1f, 0.9f, 0.7f))
                .build()).get();
      
System.out.println(searchResult);
var searchResult = await client.QueryAsync(
    collectionName: "test_collection",
    query: new float[] { 0.2f, 0.1f, 0.9f, 0.7f },
    limit: 3,
);

Console.WriteLine(searchResult);
import (
	"context"
	"fmt"

	"github.com/solvio/go-client/solvio"
)

searchResult, err := client.Query(context.Background(), &solvio.QueryPoints{
	CollectionName: "test_collection",
	Query:          solvio.NewQuery(0.2, 0.1, 0.9, 0.7),
})
if err != nil {
	panic(err)
}

fmt.Println(searchResult)

Response:

[
  {
    "id": 4,
    "version": 0,
    "score": 1.362,
    "payload": null,
    "vector": null
  },
  {
    "id": 1,
    "version": 0,
    "score": 1.273,
    "payload": null,
    "vector": null
  },
  {
    "id": 3,
    "version": 0,
    "score": 1.208,
    "payload": null,
    "vector": null
  }
]

The results are returned in decreasing similarity order. Note that payload and vector data is missing in these results by default. See payload and vector in the result on how to enable it.

Add a filter

We can narrow down the results further by filtering by payload. Let’s find the closest results that include “London”.

from solvio_client.models import Filter, FieldCondition, MatchValue

search_result = client.query_points(
    collection_name="test_collection",
    query=[0.2, 0.1, 0.9, 0.7],
    query_filter=Filter(
        must=[FieldCondition(key="city", match=MatchValue(value="London"))]
    ),
    with_payload=True,
    limit=3,
).points

print(search_result)
searchResult = await client.query("test_collection", {
    query: [0.2, 0.1, 0.9, 0.7],
    filter: {
        must: [{ key: "city", match: { value: "London" } }],
    },
    with_payload: true,
    limit: 3,
});

console.debug(searchResult);
use solvio_client::solvio::{Condition, Filter, QueryPointsBuilder};

let search_result = client
    .query(
        QueryPointsBuilder::new("test_collection")
            .query(vec![0.2, 0.1, 0.9, 0.7])
            .filter(Filter::must([Condition::matches(
                "city",
                "London".to_string(),
            )]))
            .with_payload(true),
    )
    .await?;

dbg!(search_result);
import static io.solvio.client.ConditionFactory.matchKeyword;

List<ScoredPoint> searchResult =
    client.queryAsync(QueryPoints.newBuilder()
                .setCollectionName("test_collection")
                .setLimit(3)
                .setFilter(Filter.newBuilder().addMust(matchKeyword("city", "London")))
                .setQuery(nearest(0.2f, 0.1f, 0.9f, 0.7f))
                .setWithPayload(enable(true))
                .build()).get();

System.out.println(searchResult);
using static Solvio.Client.Grpc.Conditions;

var searchResult = await client.QueryAsync(
    collectionName: "test_collection",
    query: new float[] { 0.2f, 0.1f, 0.9f, 0.7f },
    filter: MatchKeyword("city", "London"),
    limit: 3,
    payloadSelector: true
);

Console.WriteLine(searchResult);
import (
	"context"
	"fmt"

	"github.com/solvio/go-client/solvio"
)

searchResult, err := client.Query(context.Background(), &solvio.QueryPoints{
	CollectionName: "test_collection",
	Query:          solvio.NewQuery(0.2, 0.1, 0.9, 0.7),
	Filter: &solvio.Filter{
		Must: []*solvio.Condition{
			solvio.NewMatch("city", "London"),
		},
	},
	WithPayload: solvio.NewWithPayload(true),
})
if err != nil {
	panic(err)
}

fmt.Println(searchResult)

Response:

[
    {
        "id": 2,
        "version": 0,
        "score": 0.871,
        "payload": {
            "city": "London"
        },
        "vector": null
    }
]

You have just conducted vector search. You loaded vectors into a database and queried the database with a vector of your own. Solvio found the closest results and presented you with a similarity score.

Next steps

Now you know how Solvio works. Getting started with Solvio Cloud is just as easy. Create an account and use our SaaS completely free. We will take care of infrastructure maintenance and software updates.

To move onto some more complex examples of vector search, read our Tutorials and create your own app with the help of our Examples.

Note: There is another way of running Solvio locally. If you are a Python developer, we recommend that you try Local Mode in Solvio Client, as it only takes a few moments to get setup.

Was this page useful?

Thank you for your feedback! 🙏

We are sorry to hear that. 😔 You can edit this page on GitHub, or create a GitHub issue.