in Elastic.SemanticKernel.Connectors.Elasticsearch/ElasticsearchVectorStoreCollectionSearchMapping.cs [29:98]
public static ICollection<Query> BuildFilter(VectorSearchFilter? basicVectorSearchFilter, Dictionary<VectorStoreRecordProperty, string> propertyToStorageName)
{
Verify.NotNull(propertyToStorageName);
if (basicVectorSearchFilter is null)
{
return [];
}
var filterClauses = basicVectorSearchFilter.FilterClauses.ToArray();
var filterQueries = new List<Query>();
foreach (var filterClause in filterClauses)
{
switch (filterClause)
{
case EqualToFilterClause equalToClause:
{
var mapping = GetPropertyNameMapping(equalToClause.FieldName);
VerifyFilterable(mapping.Key);
filterQueries.Add(Query.Term(new TermQuery(mapping.Value!)
{
Value = FieldValueFromValue(equalToClause.Value)
}));
break;
}
case AnyTagEqualToFilterClause anyTagEqualToClause:
{
var mapping = GetPropertyNameMapping(anyTagEqualToClause.FieldName);
VerifyFilterable(mapping.Key);
filterQueries.Add(Query.Terms(new TermsQuery
{
Field = mapping.Value!,
Terms = new TermsQueryField([FieldValueFromValue(anyTagEqualToClause.Value)])
}));
break;
}
default:
throw new NotSupportedException($"Filter clause of type {filterClause.GetType().FullName} is not supported.");
}
}
return filterQueries;
KeyValuePair<VectorStoreRecordProperty, string> GetPropertyNameMapping(string dataModelPropertyName)
{
var result = propertyToStorageName
.FirstOrDefault(x => string.Equals(x.Key.DataModelPropertyName, dataModelPropertyName, StringComparison.Ordinal));
if (result.Key is null)
{
throw new NotSupportedException($"Property '{dataModelPropertyName}' is not supported as a filter value.");
}
return result;
}
static void VerifyFilterable(VectorStoreRecordProperty property)
{
if (property is not VectorStoreRecordDataProperty { IsFilterable: true })
{
throw new NotSupportedException($"Property '{property.DataModelPropertyName}' can not be used for filtering.");
}
}
}