Aerx.QdrantClient.Http 1.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package Aerx.QdrantClient.Http --version 1.0.1
NuGet\Install-Package Aerx.QdrantClient.Http -Version 1.0.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Aerx.QdrantClient.Http" Version="1.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Aerx.QdrantClient.Http --version 1.0.1
#r "nuget: Aerx.QdrantClient.Http, 1.0.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Aerx.QdrantClient.Http as a Cake Addin
#addin nuget:?package=Aerx.QdrantClient.Http&version=1.0.1

// Install Aerx.QdrantClient.Http as a Cake Tool
#tool nuget:?package=Aerx.QdrantClient.Http&version=1.0.1

.NET SDK for Qdrant vector database

Build Status NuGet Release

.NET SDK for Qdrant vector database.

Getting started

Creating a client

A client that will connect to Qdrant HTTP API on http://localhost:6334 can be instantiated as follows

var client = new QdrantHttpClient("localhost");

Additional constructor overloads provide more control over how the client is configured. The following example configures a client to use the different Qdrant port and an api key:

var client = new QdrantHttpClient(
    httpAddress: "localhost", 
    port: 1567, 
    apiKey : "my-secret-api-key"
);

Working with collections

Once a client has been created, create a new collection

var collectionCreationResult = await _qdrantHttpClient.CreateCollection(
    "my_collection",
    new CreateCollectionRequest(VectorDistanceMetric.Dot, vectorSize: 100, isServeVectorsFromDisk: true)
    {
        OnDiskPayload = true
    },
    cancellationToken
);
Insert vectors into a collection
var upsertPoints = Enumerable.Range(0, 100).Select(
    i => new UpsertPointsRequest<TestPayload>.UpsertPoint(
        PointId.Integer((ulong) i),
        Enumerable.Range(0, 128)
            .Select(_ => float.CreateTruncating(Random.Shared.NextDouble()))
            .ToArray(),
        new TestPayload()
        {
            Integer = 123,
            Text = "test"
        }
    )
).ToList();

var upsertPointsResult = await _qdrantHttpClient.UpsertPoints(
    "my_collection",
    new UpsertPointsRequest<TestPayload>()
    {
        Points = upsertPoints
    },
    cancellationToken
);
Search for similar vectors
var queryVector = Enumerable.Range(0, 128)
    .Select(_ => float.CreateTruncating(Random.Shared.NextDouble()))
    .ToArray()

// return the 5 closest points
var searchResult = await _qdrantHttpClient.SearchPoints(
    "my_collection",
    new SearchPointsRequest(
        queryVector,
        limit: 5)
    {
        WithVector = false,
        WithPayload = PayloadPropertiesSelector.All
    },
    cancellationToken
);
Search for similar vectors with filtering condition
 var searchResult = await _qdrantHttpClient.SearchPoints(
    "my_collection",
    new SearchPointsRequest(
        queryVector,
        limit: 5)
    {
        WithVector = false,
        WithPayload = PayloadPropertiesSelector.All,
        Filter = 
            Q.Must(
                Q.BeInRange("int_field", greaterThanOrEqual: 0)
            )
            +
            !(
                Q.MatchValue("int_field_2", 1567)
                &
                Q.MatchValue("text_field", "test")
            )
    },
    cancellationToken
);
Search for similar vectors with filtering condition on typed payload

Here we are using typed builders for building filters for typed payload.

 var searchResult = await _qdrantHttpClient.SearchPoints(
    "my_collection",
    new SearchPointsRequest(
        queryVector,
        limit: 5)
    {
        WithVector = false,
        WithPayload = PayloadPropertiesSelector.All,
        Filter = 
            Q.Must(
                Q<TestPayload>.BeInRange(p => p.Integer, greaterThanOrEqual: 0)
            )
            |
            !Q.Must(
                Q<TestPayload>.MatchValue(p => p.Integer, 1)
            )
    },
    cancellationToken
);

Building collections

Conditions are built using Q (from Qdrant or Query) and Q<TPayload> condition builders. Top level filter should contain only Must, MustNot or Should condition groups. Result if any call on Q or Q<TPayload> is implicitly convertible to QdrantFilter, that is accepted everywhere the filter is expected, for ease of use. QdrantFilter can be directly directly using QdrantFilter.Create() factory method.

Non-generic condition builder Q

Non-generic condition builder methods other than Must, MustNot, Should and Nested accept string payload field name as the first parameter.

Q.Must(
    Q.MatchValue("test_key", 123),
    Q.MatchValue("test_key_2", "test_value")
)

Filters can be nested.

Q.Should(
    Q.MustNot(Q.MatchValue("test_key", 123)),
    Q.MatchValue("test_key_2", "test_value")
)
Generic condition builder Q<T>

If the type of the payload is known beforehand the generic version of condition builder Q<TPayload> can be used to avoid typos in payload field names. Q<TPayload> has the same methods but with payload field selector expression as the first parameter.

If the payload is as defined as follows

public class TestPayload : Payload
{
    public string Text { get; set; }

    [JsonPropertyName("int")]
    public int? IntProperty { get; set; }

    public NestedClass Nested { get; set; }

    public class NestedClass
    {
        public string Name { get; set; }

        public double Double { set; get; }

        public int Integer { get; set; }
    }
}

Filter can access its structure to derive the payload filed names. Property renames in payload json are supported through standard JsonPropertyNameAttribute. Property nesting is also suppoerted in this case json dot-notation path will be constructed.

Q.Should(
    Q<TestPayload>.MatchValue(p=>p.IntProperty, 123),
    Q<TestPayload>.MatchValue(p=>p.Nested.Name, "test_value")
)
Filter combination operators

In addition to combining filters explicitly, the more terse combination is possible through the use of operators + , |, & and !.

  • + - combines top level filter conditions to simplify filter building.

    Q.Must(
        Q.BeInRange("int_field", greaterThanOrEqual: 0)
    )
    +
    Q.MustNot(
        Q.MatchValue("int_field_2", 1567)
    )
    

    Which is equivalent to the following filter json

    {
        "must": [
            {
                "key": "int_field",
                "range": {
                    "gte": 0
                }
            }
        ],
        "must_not": [
            {
                "key": "int_field_2",
                "match": {
                    "value": 1567
                }
            }
        ]
    }
    
  • | combines two conditions using Should condiiton group. Nested Should groups are automatically unwrapped.

    Q.Must(
        Q.BeInRange("int_field", greaterThanOrEqual: 0)
    )
    |
    Q.Should(
        Q.MatchValue("int_field_2", 1567)
    )
    

    Which is equivalent to the following filter json

    {
        "should": [
            {
                "must": [
                    {
                        "key": "int_field",
                        "range": {
                            "gte": 0
                        }
                    }
                ]
            },
            {
                "key": "int_field_2",
                "match": {
                    "value": 1567
                }
            }
        ]
    }
    
  • & combines two conditions using Must condiiton group. Nested Must groups are automatically unwrapped.

    Q.MustNot(
        Q.BeInRange("int_field", greaterThanOrEqual: 0)
    )
    &
    Q.Must(
        Q.MatchValue("int_field_2", 1567)
    )
    

    Which is equivalent to the following filter json

    {
        "must": [
            {
                "must_not": [
                    {
                        "key": "int_field",
                        "range": {
                            "gte": 0
                        }
                    }
                ]
            },
            {
                "key": "int_field_2",
                "match": {
                    "value": 1567
                }
            }
        ]
    }
    
  • ! wraps condition in MustNot condition group. Negates nested Must and MustNot condition groups.

    Q.Should(
        Q<TestPayload>.MatchValue(p=>p.IntProperty, 123),
        !Q<TestPayload>.MatchValue(p=>p.Nested.Name, "test_value")
    )
    +
    !Q.Must(
        Q<TestPayload>.MatchValue(p=>p.IntProperty, 345)
    )
    

    Which is equivalent to the following filter json

    {
        "should": [
            {
                "key": "int_property",
                "match": {
                    "value": 123
                }
            },
            {
                "must_not": [
                    {
                        "key": "nested.name",
                        "match": {
                            "value": "test_value"
                        }
                    }
                ]
            }
        ],
        "must_not": [
            {
                "key": "int_property",
                "match": {
                    "value": 345
                }
            }
        ]
    }
    
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.9.8 111 5/15/2024
1.9.7 79 5/15/2024
1.9.6 61 5/13/2024
1.9.5 57 5/13/2024
1.9.4 98 5/6/2024
1.9.3 47 5/2/2024
1.9.2 45 5/2/2024
1.9.1 90 4/27/2024
1.9.0 103 4/27/2024
1.8.0 83 4/26/2024
1.7.3 122 3/29/2024
1.7.2 100 2/26/2024
1.7.1 82 2/26/2024
1.7.0 93 2/19/2024
1.0.1 190 12/6/2023
1.0.0 98 12/6/2023