From 6bb1a8da2810ab960f3b023b6e38603e42c9a15b Mon Sep 17 00:00:00 2001 From: Jason Pollentier <802805+grossvogel@users.noreply.github.com> Date: Tue, 6 Jun 2023 19:14:38 -0500 Subject: [PATCH] feat: metadata filtering (#12) --- lib/pinecone.ex | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/pinecone.ex b/lib/pinecone.ex index 0662f29..32b5599 100644 --- a/lib/pinecone.ex +++ b/lib/pinecone.ex @@ -286,6 +286,7 @@ defmodule Pinecone do @doc """ Deletes all vectors from the given Pinecone index. + If the filter option is passed, deletes only vectors that match the given metadata filter ## Options @@ -294,16 +295,22 @@ defmodule Pinecone do * `:config` - client configuration used to override application level configuration. Defaults to `nil` + + * `:filter` - metadata filter to apply to the deletion. See https://docs.pinecone.io/docs/metadata-filtering """ @spec delete_all_vectors(index :: index_type(), opts :: keyword()) :: success_type(String.t()) | error_type() def delete_all_vectors(%Index{name: name, project_name: project_name}, opts \\ []) do - opts = Keyword.validate!(opts, [:config, :namespace]) + opts = Keyword.validate!(opts, [:config, :namespace, :filter]) - params = [{"delete_all", true}] - params = if opts[:namespace], do: [{"namespace", opts[:namespace]} | params], else: params + body = + if is_map(opts[:filter]), + do: %{"filter" => opts[:filter]}, + else: %{"deleteAll" => true} - delete({:vectors, "#{name}-#{project_name}"}, "vectors/delete", opts[:config], params: params) + body = if opts[:namespace], do: Map.put(body, "namespace", opts[:namespace]), else: body + + post({:vectors, "#{name}-#{project_name}"}, "vectors/delete", body, opts[:config]) end @doc """ @@ -323,6 +330,8 @@ defmodule Pinecone do * `:namespace` - index namespace to query. Defaults to `nil` which will query vectors in the default namespace + * `:filter` - metadata filter to apply to the query. See https://docs.pinecone.io/docs/metadata-filtering + * `:config` - client configuration used to override application level configuration. Defaults to `nil` """ @@ -335,18 +344,21 @@ defmodule Pinecone do :namespace, top_k: 5, include_values: false, - include_metadata: false + include_metadata: false, + filter: %{} ]) validate!("top_k", opts[:top_k], :non_negative_integer) validate!("include_values", opts[:include_values], :boolean) validate!("include_metadata", opts[:include_metadata], :boolean) + validate!("filter", opts[:filter], :map) body = %{ "vector" => vector, "topK" => opts[:top_k], "includeValues" => opts[:include_values], - "includeMetadata" => opts[:include_metadata] + "includeMetadata" => opts[:include_metadata], + "filter" => opts[:filter] } body = if opts[:namespace], do: Map.put(body, "namespace", opts[:namespace]), else: body @@ -434,6 +446,7 @@ defmodule Pinecone do defp validate!(_key, value, :non_negative_integer) when is_integer(value) and value > 0, do: :ok defp validate!(_key, value, :boolean) when is_boolean(value), do: :ok defp validate!(_key, value, :binary) when is_binary(value), do: :ok + defp validate!(_key, value, :map) when is_map(value), do: :ok defp validate!(key, value, type) do raise ArgumentError, "expected #{key} to be type #{inspect(type)}, got #{inspect(value)}"