/* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/
using System;
using System.Runtime.Serialization;
using OpenSearch.Net.Utf8Json;
namespace OpenSearch.Client;
///
/// An approximate k-NN query.
///
[InterfaceDataContract]
[JsonFormatter(typeof(FieldNameQueryFormatter))]
public interface IKnnQuery : IFieldNameQuery
{
///
/// The vector to search for.
///
[DataMember(Name = "vector")]
float[] Vector { get; set; }
///
/// The number of neighbors the search of each graph will return.
///
[DataMember(Name = "k")]
int? K { get; set; }
///
/// The result restriction filter query.
///
[DataMember(Name = "filter")]
IQueryContainer Filter { get; set; }
}
[DataContract]
public class KnnQuery : FieldNameQueryBase, IKnnQuery
{
///
public float[] Vector { get; set; }
///
public int? K { get; set; }
///
public IQueryContainer Filter { get; set; }
protected override bool Conditionless => IsConditionless(this);
internal override void InternalWrapInContainer(IQueryContainer container) => container.Knn = this;
internal static bool IsConditionless(IKnnQuery q) => q.Vector == null || q.Vector.Length == 0 || q.K == null || q.K == 0 || q.Field.IsConditionless();
}
public class KnnQueryDescriptor
: FieldNameQueryDescriptorBase, IKnnQuery, T>,
IKnnQuery
where T : class
{
protected override bool Conditionless => KnnQuery.IsConditionless(this);
float[] IKnnQuery.Vector { get; set; }
int? IKnnQuery.K { get; set; }
IQueryContainer IKnnQuery.Filter { get; set; }
///
public KnnQueryDescriptor Vector(params float[] vector) => Assign(vector, (a, v) => a.Vector = v);
///
public KnnQueryDescriptor K(int? k) => Assign(k, (a, v) => a.K = v);
///
public KnnQueryDescriptor Filter(Func, QueryContainer> filterSelector) =>
Assign(filterSelector, (a, v) => a.Filter = v?.Invoke(new QueryContainerDescriptor()));
}