Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion src/Typesense/SearchParameters.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Typesense.Converter;

Expand Down Expand Up @@ -81,8 +82,41 @@ public record SearchParameters
/// be treated as a prefix, and not as a whole word. This is used for building
/// autocomplete and instant search interfaces. Defaults to true.
/// </summary>
/// <remarks>Backwards compatible implementation for existing clients.</remarks>
[JsonPropertyName("_prefix")]
public bool? Prefix
{
get => PrefixList == null ? null : PrefixList.Count > 0 ? PrefixList[0] : null;
set
{
if (value != null)
{
if (PrefixList == null)
{
PrefixList = new List<bool>();
}
if(PrefixList.Count == 0)
{
PrefixList.Add(value.Value);
}
else
{
PrefixList[0] = value.Value!;
}
}
}
}

/// <summary>
/// List of boolean fields to indicate that the last word in the query should
/// be treated as a prefix, and not as a whole word. This is used for building
/// autocomplete and instant search interfaces.
/// For example, if you are querying 3 fields and want to enable prefix searching only on the first field
/// you can set the prefix property to [true, false, false].
/// Defaults to true.
/// </summary>
[JsonPropertyName("prefix")]
public bool? Prefix { get; set; }
public List<bool> PrefixList { get; set; }

/// <summary>
/// If infix index is enabled for this field, infix searching can be done on a per-field basis by sending a comma separated string parameter called infix to the search query.
Expand Down
6 changes: 6 additions & 0 deletions src/Typesense/TypesenseClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,12 @@ private static string CreateUrlParameters<T>(T queryParameters)
null => null,
true => "true",
false => "false",
List<bool> list => string.Join(",",
list.Select(v => v switch
{
true => "true",
false => "false"
})),
Enum e => e.ToString().ToLowerInvariant(),
_ => value.ToString(),
};
Expand Down
56 changes: 56 additions & 0 deletions test/Typesense.Tests/TypesenseClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1500,6 +1500,62 @@ public async Task Search_query_by_two_fields()
}
}

[Fact, TestPriority(11)]
public async Task Search_query_with_prefix_true_should_work()
{
var expected = new Company
{
Id = "124",
CompanyName = "Stark Industries",
NumEmployees = 6000,
Location = new Location
{
City = "Phoenix",
Country = "USA"
},
};

var query = new SearchParameters("Stark", "company_name")
{
Prefix = true
};
var response = await _client.Search<Company>("companies", query);

using (var scope = new AssertionScope())
{
response.Found.Should().Be(1);
response.Hits.First().Document.Should().BeEquivalentTo(expected);
}
}

[Fact, TestPriority(11)]
public async Task Search_query_with_prefix_list_should_work()
{
var expected = new Company
{
Id = "124",
CompanyName = "Stark Industries",
NumEmployees = 6000,
Location = new Location
{
City = "Phoenix",
Country = "USA"
},
};

var query = new SearchParameters("Stark", "company_name,location.country")
{
PrefixList = new List<bool> { true, false }
};
var response = await _client.Search<Company>("companies", query);

using (var scope = new AssertionScope())
{
response.Found.Should().Be(1);
response.Hits.First().Document.Should().BeEquivalentTo(expected);
}
}

[Fact, TestPriority(11)]
public async Task Search_facet_by_country()
{
Expand Down