diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 454efca6..d25cc2ff 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -843,3 +843,18 @@ facet_search_3: |- FacetQuery = "c" }; await client.Index("books").FacetSearchAsync("genres", query); +search_parameter_reference_locales_1: |- + var searchQuery = new SearchQuery { Locales = new[] { "jpn" } }; + await client.index('INDEX_NAME').SearchAsync('進撃の巨人', searchQuery); +get_localized_attribute_settings_1: |- + await client.index('INDEX_NAME').GetLocalizedAttributesAsync() +update_localized_attribute_settings_1: |- + await client.index('INDEX_NAME').UpdateLocalizedAttributesAsync(new LocalizedAttributeLocale[] + { + new LocalizedAttributeLocale() { + Locales = new[] { "jpn" }, + AttributePatterns = new[] { "*_ja" } + } + }); +reset_localized_attribute_settings_1: |- + await client.index('INDEX_NAME').ResetLocalizedAttributesAsync(); diff --git a/src/Meilisearch/Index.Attributes.cs b/src/Meilisearch/Index.Attributes.cs index b808f57b..ee93af85 100644 --- a/src/Meilisearch/Index.Attributes.cs +++ b/src/Meilisearch/Index.Attributes.cs @@ -119,6 +119,43 @@ public async Task ResetFilterableAttributesAsync(CancellationToken can return await httpresponse.Content.ReadFromJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false); } + /// + /// Gets the localized attributes setting. + /// + /// The cancellation token for this call. + /// Returns the localized attributes setting. + public async Task> GetLocalizedAttributesAsync(CancellationToken cancellationToken = default) + { + return await _http.GetFromJsonAsync>($"indexes/{Uid}/settings/localized-attributes", cancellationToken: cancellationToken) + .ConfigureAwait(false); + } + + /// + /// Updates the localized attributes setting. + /// + /// Collection of localized attributes. + /// The cancellation token for this call. + /// Returns the task info of the asynchronous task. + public async Task UpdateLocalizedAttributesAsync(IEnumerable localizedAttributes, CancellationToken cancellationToken = default) + { + var responseMessage = + await _http.PutAsJsonAsync($"indexes/{Uid}/settings/localized-attributes", localizedAttributes, Constants.JsonSerializerOptionsRemoveNulls, cancellationToken: cancellationToken) + .ConfigureAwait(false); + return await responseMessage.Content.ReadFromJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false); + } + + /// + /// Resets the filterable attributes setting. + /// + /// The cancellation token for this call. + /// Returns the task info of the asynchronous task. + public async Task ResetLocalizedAttributesAsync(CancellationToken cancellationToken = default) + { + var httpresponse = await _http.DeleteAsync($"indexes/{Uid}/settings/localized-attributes", cancellationToken) + .ConfigureAwait(false); + return await httpresponse.Content.ReadFromJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false); + } + /// /// Gets the searchable attributes setting. /// diff --git a/src/Meilisearch/LocalizedAttributeLocale.cs b/src/Meilisearch/LocalizedAttributeLocale.cs new file mode 100644 index 00000000..f48b882b --- /dev/null +++ b/src/Meilisearch/LocalizedAttributeLocale.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Meilisearch +{ + /// + /// Localized attribute locale. + /// + public class LocalizedAttributeLocale + { + /// + /// Gets or sets the locales. + /// + [JsonPropertyName("locales")] + public IEnumerable Locales { get; set; } + + /// + /// Gets or sets the attribute patterns. + /// + [JsonPropertyName("attributePatterns")] + public IEnumerable AttributePatterns { get; set; } + } +} diff --git a/src/Meilisearch/SearchQuery.cs b/src/Meilisearch/SearchQuery.cs index fcfcbf19..44c1c097 100644 --- a/src/Meilisearch/SearchQuery.cs +++ b/src/Meilisearch/SearchQuery.cs @@ -148,5 +148,11 @@ public class SearchQuery /// [JsonPropertyName("rankingScoreThreshold")] public decimal? RankingScoreThreshold { get; set; } + + /// + /// Gets or sets locales. + /// + [JsonPropertyName("locales")] + public IEnumerable Locales { get; set; } } } diff --git a/src/Meilisearch/Settings.cs b/src/Meilisearch/Settings.cs index a926cc88..5bb6111b 100644 --- a/src/Meilisearch/Settings.cs +++ b/src/Meilisearch/Settings.cs @@ -62,6 +62,12 @@ public class Settings [JsonPropertyName("filterableAttributes")] public IEnumerable FilterableAttributes { get; set; } + /// + /// Gets or sets the localized attributes. + /// + [JsonPropertyName("localizedAttributes")] + public IEnumerable LocalizedAttributes { get; set; } + /// /// Gets or sets the sortable attributes. /// diff --git a/tests/Meilisearch.Tests/SearchTests.cs b/tests/Meilisearch.Tests/SearchTests.cs index 328b2143..b8af9064 100644 --- a/tests/Meilisearch.Tests/SearchTests.cs +++ b/tests/Meilisearch.Tests/SearchTests.cs @@ -554,5 +554,14 @@ public async Task CustomSearchWithRankingScoreThreshold() movies.Hits.First().Id.Should().Be("13"); movies.Hits.First().Name.Should().Be("Harry Potter"); } + + [Fact] + public async Task CustomSearchWithLocalizedAttribute() + { + var searchQuery = new SearchQuery { Locales = new[] { "eng" } }; + var movies = await _nestedIndex.SearchAsync("a wizard movie", searchQuery); + + movies.Hits.Count.Should().Be(4); + } } } diff --git a/tests/Meilisearch.Tests/SettingsTests.cs b/tests/Meilisearch.Tests/SettingsTests.cs index 395bc54a..af90f449 100644 --- a/tests/Meilisearch.Tests/SettingsTests.cs +++ b/tests/Meilisearch.Tests/SettingsTests.cs @@ -97,6 +97,13 @@ public async Task UpdateSettings() DistinctAttribute = "name", Dictionary = new string[] { "dictionary" }, SearchCutoffMs = 1000, + LocalizedAttributes = new LocalizedAttributeLocale[] + { + new LocalizedAttributeLocale() { + Locales = new[] { "eng" }, + AttributePatterns = new[] { "en_*" } + } + } }; await AssertUpdateSuccess(_index.UpdateSettingsAsync, newSettings); await AssertGetInequality(_index.GetSettingsAsync, newSettings); // fields omitted in newSettings shouldn't have changed @@ -232,6 +239,45 @@ public async Task ResetFilterableAttributes() await AssertGetEquality(_index.GetFilterableAttributesAsync, _defaultSettings.FilterableAttributes); } + [Fact] + public async Task GetLocaliztedAttributes() + { + await AssertGetEquality(_index.GetLocalizedAttributesAsync, _defaultSettings.LocalizedAttributes); + } + + [Fact] + public async Task UpdateLocalizedAttributes() + { + var newLocalizedAttributes = new LocalizedAttributeLocale[] + { + new LocalizedAttributeLocale() { + Locales = new[] { "eng" }, + AttributePatterns = new[] { "en_*" } + } + }; + + await AssertUpdateSuccess(_index.UpdateLocalizedAttributesAsync, newLocalizedAttributes); + await AssertGetEquality(_index.GetLocalizedAttributesAsync, newLocalizedAttributes); + } + + [Fact] + public async Task ResetLocalizedAttributes() + { + var newLocalizedAttributes = new LocalizedAttributeLocale[] + { + new LocalizedAttributeLocale() { + Locales = new[] { "eng" }, + AttributePatterns = new[] { "en_*" } + } + }; + + await AssertUpdateSuccess(_index.UpdateLocalizedAttributesAsync, newLocalizedAttributes); + await AssertGetEquality(_index.GetLocalizedAttributesAsync, newLocalizedAttributes); + + await AssertResetSuccess(_index.ResetLocalizedAttributesAsync); + await AssertGetEquality(_index.GetLocalizedAttributesAsync, _defaultSettings.LocalizedAttributes); + } + [Fact] public async Task GetRankingRules() { @@ -682,7 +728,8 @@ private static Settings SettingsWithDefaultedNullFields(Settings inputSettings, Pagination = inputSettings.Pagination ?? defaultSettings.Pagination, ProximityPrecision = inputSettings.ProximityPrecision ?? defaultSettings.ProximityPrecision, Dictionary = inputSettings.Dictionary ?? defaultSettings.Dictionary, - SearchCutoffMs = inputSettings.SearchCutoffMs ?? defaultSettings.SearchCutoffMs + SearchCutoffMs = inputSettings.SearchCutoffMs ?? defaultSettings.SearchCutoffMs, + LocalizedAttributes = inputSettings.LocalizedAttributes ?? defaultSettings.LocalizedAttributes }; }