diff --git a/.circleci/config.yml b/.circleci/config.yml
index 5a077e4..5c538d8 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -13,7 +13,7 @@ executors:
auth:
username: $DOCKER_LOGIN
password: $DOCKER_ACCESSTOKEN
- - image: typesense/typesense:0.22.2 # For integration testing
+ - image: typesense/typesense:0.23.0 # For integration testing
auth:
username: $DOCKER_LOGIN
password: $DOCKER_ACCESSTOKEN
diff --git a/README.md b/README.md
index 736f426..39ed946 100644
--- a/README.md
+++ b/README.md
@@ -297,7 +297,7 @@ var deleteSynonym = await typesenseClient.DeleteSynonym("Addresses", "Address_Sy
### Typesense API Errors
-Typesense API exceptions in the [Typesense-api-errors](https://typesense.org/docs/0.22.2/api/api-errors.html) spec.
+Typesense API exceptions in the [Typesense-api-errors](https://typesense.org/docs/0.23.0/api/api-errors.html) spec.
| Type | Description |
|:-------------------------------------------|:---------------------------------------------------------------------------|
@@ -331,5 +331,5 @@ dotnet test --filter Category=Integration
To enable running integration tests you can run Typesense in a docker container using the command below.
```sh
-docker run -p 8108:8108 -v/tmp/data:/data typesense/typesense:0.22.2 --data-dir /data --api-key=key
+docker run -p 8108:8108 -v/tmp/data:/data typesense/typesense:0.23.0 --data-dir /data --api-key=key
```
diff --git a/src/Typesense/Field.cs b/src/Typesense/Field.cs
index d469f45..4ccff96 100644
--- a/src/Typesense/Field.cs
+++ b/src/Typesense/Field.cs
@@ -17,6 +17,8 @@ public record Field
public bool? Optional { get; init; }
[JsonPropertyName("index")]
public bool? Index { get; init; }
+ [JsonPropertyName("sort")]
+ public bool? Sort { get; init; }
public Field(string name, FieldType type)
{
@@ -39,7 +41,6 @@ public Field(string name, FieldType type, bool facet, bool? optional)
Optional = optional;
}
- [JsonConstructor]
public Field(string name, FieldType type, bool facet, bool? optional, bool? index)
{
Name = name;
@@ -49,6 +50,22 @@ public Field(string name, FieldType type, bool facet, bool? optional, bool? inde
Index = index;
}
+ [JsonConstructor]
+ public Field(string name,
+ FieldType type,
+ bool facet,
+ bool? optional,
+ bool? index,
+ bool? sort)
+ {
+ Name = name;
+ Type = type;
+ Facet = facet;
+ Optional = optional;
+ Index = index;
+ Sort = sort;
+ }
+
[Obsolete("A better choice going forward is using the constructor with 'FieldType' enum instead.")]
public Field(string name, string type, bool facet, bool optional = false, bool index = true)
{
diff --git a/src/Typesense/ImportType.cs b/src/Typesense/ImportType.cs
index 3649def..8d315e8 100644
--- a/src/Typesense/ImportType.cs
+++ b/src/Typesense/ImportType.cs
@@ -4,5 +4,6 @@ public enum ImportType
{
Create,
Upsert,
- Update
+ Update,
+ Emplace
}
diff --git a/src/Typesense/SearchParameters.cs b/src/Typesense/SearchParameters.cs
index d76d49c..38f4a05 100644
--- a/src/Typesense/SearchParameters.cs
+++ b/src/Typesense/SearchParameters.cs
@@ -190,12 +190,28 @@ public record SearchParameters
///
public bool? PreSegmentedQuery { get; set; }
+ ///
+ /// Treat space as typo: search for q=basket ball if q=basketball is not found or vice-versa.
+ ///
+ public bool? SplitJoinTokens { get; set; }
+
///
/// If you have some overrides defined but want to disable all of them during
/// query time, you can do that by setting this parameter to false
///
public bool? EnableOverrides { get; set; }
+ ///
+ /// Control the number of words that Typesense considers for typo and prefix searching.
+ /// Default: 4 (or 10000 if exhaustive_search is enabled).
+ ///
+ public int? MaxCandiates { get; set; }
+
+ ///
+ /// Controls the fuzziness of the facet query filter.
+ ///
+ public int? FacetQueryNumberTypos { get; set; }
+
[Obsolete("Use multi-arity constructor instead.")]
public SearchParameters()
{
diff --git a/src/Typesense/TypesenseClient.cs b/src/Typesense/TypesenseClient.cs
index afb7a78..e05ffff 100644
--- a/src/Typesense/TypesenseClient.cs
+++ b/src/Typesense/TypesenseClient.cs
@@ -170,6 +170,9 @@ public async Task> ImportDocuments(
case ImportType.Upsert:
path += "&action=upsert";
break;
+ case ImportType.Emplace:
+ path += "&action=emplace";
+ break;
default:
throw new ArgumentException($"Could not handle {nameof(ImportType)} with name '{Enum.GetName(importType)}'", nameof(importType));
}
@@ -442,6 +445,12 @@ private static string CreateUrlSearchParameters(SearchParameters searchParameter
urlParameters += $"&pre_segmented_query={searchParameters.PreSegmentedQuery.Value.ToString().ToLowerInvariant()}";
if (searchParameters.EnableOverrides is not null)
urlParameters += $"&enable_overrides={searchParameters.EnableOverrides.Value.ToString().ToLowerInvariant()}";
+ if (searchParameters.SplitJoinTokens is not null)
+ urlParameters += $"&split_join_tokens={searchParameters.SplitJoinTokens.Value.ToString().ToLowerInvariant()}";
+ if (searchParameters.MaxCandiates is not null)
+ urlParameters += $"&max_candidates={searchParameters.MaxCandiates.Value.ToString().ToLowerInvariant()}";
+ if (searchParameters.FacetQueryNumberTypos is not null)
+ urlParameters += $"&facet_query_num_typos={searchParameters.FacetQueryNumberTypos.Value.ToString().ToLowerInvariant()}";
return urlParameters;
}
diff --git a/test/Typesense.Tests/TypesenseClientTests.cs b/test/Typesense.Tests/TypesenseClientTests.cs
index fd0cf32..8c8ce82 100644
--- a/test/Typesense.Tests/TypesenseClientTests.cs
+++ b/test/Typesense.Tests/TypesenseClientTests.cs
@@ -39,9 +39,9 @@ public async Task Create_schema()
0,
new List
{
- new Field("company_name", FieldType.String, false, false, true),
- new Field("num_employees", FieldType.Int32, false, false, true),
- new Field("country", FieldType.String, true, false, true),
+ new Field("company_name", FieldType.String, false, false, true, false),
+ new Field("num_employees", FieldType.Int32, false, false, true, true),
+ new Field("country", FieldType.String, true, false, true, false),
},
"num_employees");
@@ -70,7 +70,7 @@ public async Task Create_schema_with_wildcard_field()
0,
new List
{
- new Field(".*", FieldType.String, false, true, true),
+ new Field(".*", FieldType.String, false, true, true, false),
},
"");
@@ -97,9 +97,9 @@ public async Task Retrieve_collection()
0,
new List
{
- new Field("company_name", FieldType.String, false, false, true),
- new Field("num_employees", FieldType.Int32, false, false, true),
- new Field("country", FieldType.String, true, false, true),
+ new Field("company_name", FieldType.String, false, false, true, false),
+ new Field("num_employees", FieldType.Int32, false, false, true, true),
+ new Field("country", FieldType.String, true, false, true, false),
},
"num_employees");
@@ -118,9 +118,9 @@ public async Task Retrieve_collections()
0,
new List
{
- new Field("company_name", FieldType.String, false, false, true),
- new Field("num_employees", FieldType.Int32, false, false, true),
- new Field("country", FieldType.String, true, false, true),
+ new Field("company_name", FieldType.String, false, false, true, false),
+ new Field("num_employees", FieldType.Int32, false, false, true, true),
+ new Field("country", FieldType.String, true, false, true, false),
},
"num_employees")
};
@@ -137,9 +137,9 @@ public async Task Delete_collection()
0,
new List
{
- new Field("company_name", FieldType.String, false, false, true),
- new Field("num_employees", FieldType.Int32, false, false, true),
- new Field("country", FieldType.String, true, false, true),
+ new Field("company_name", FieldType.String, false, false, true, false),
+ new Field("num_employees", FieldType.Int32, false, false, true, true),
+ new Field("country", FieldType.String, true, false, true, false),
},
"num_employees");
@@ -226,7 +226,8 @@ public async Task Import_documents_create()
}
};
- var response = await _client.ImportDocuments("companies", companies, 40, ImportType.Create);
+ var response = await _client.ImportDocuments(
+ "companies", companies, 40, ImportType.Create);
response.Should().BeEquivalentTo(expected);
}
@@ -296,6 +297,39 @@ public async Task Import_documents_upsert()
response.Should().BeEquivalentTo(expected);
}
+ [Fact, TestPriority(7)]
+ public async Task Import_documents_emplace()
+ {
+ var expected = new List
+ {
+ new ImportResponse(true),
+ new ImportResponse(true),
+ };
+
+ var companies = new List
+ {
+ new Company
+ {
+ Id = "125",
+ CompanyName = "Future Technology",
+ NumEmployees = 1232,
+ Country = "UK",
+ },
+ new Company
+ {
+ Id = "126",
+ CompanyName = "Random Corp.",
+ NumEmployees = 531,
+ Country = "AU",
+ }
+ };
+
+ var response = await _client.ImportDocuments(
+ "companies", companies, 40, ImportType.Emplace);
+
+ response.Should().BeEquivalentTo(expected);
+ }
+
[Fact, TestPriority(8)]
public async Task Export_documents()
{