Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes related to the next Meilisearch release (v0.27.0) #256

Merged
merged 4 commits into from
May 18, 2022
Merged
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
50 changes: 50 additions & 0 deletions .code-samples.meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,53 @@ tenant_token_guide_generate_sdk_1: |-
tenant_token_guide_search_sdk_1: |-
frontEndClient = new MeilisearchClient("http://127.0.0.1:7700", token);
SearchResult<Patient> searchResult = await frontEndClient.Index("patient_medical_records").SearchAsync<Patient>("blood test");
get_typo_tolerance_1:
await client.Index("books").GetTypoToleranceAsync();
update_typo_tolerance_1: |-
var typoTolerance = new TypoTolerance {
DisableOnAttributes = new string[] { "title" },
MinWordSizeTypos = new TypoTolerance.TypoSize {
OneTypo = 4,
TwoTypos = 10
}
};

await client.Index("books").UpdateTypoToleranceAsync(typoTolerance);
reset_typo_tolerance_1: |-
await client.Index("books").ResetTypoToleranceAsync();
typo_tolerance_guide_1: |-
var typoTolerance = new TypoTolerance {
Enabled = false
};

await client.Index("mvoies").UpdateTypoToleranceAsync(typoTolerance);
typo_tolerance_guide_2: |-
var typoTolerance = new TypoTolerance {
DisableOnAttributes = new string[] { "title" }
};

await client.Index("mvoies").UpdateTypoToleranceAsync(typoTolerance);
typo_tolerance_guide_3: |-
var typoTolerance = new TypoTolerance {
DisableOnWords = new string[] { "shrek" }
};

await client.Index("mvoies").UpdateTypoToleranceAsync(typoTolerance);
typo_tolerance_guide_4: |-
var typoTolerance = new TypoTolerance {
MinWordSizeTypos = new TypoTolerance.TypoSize {
OneTypo = 4,
TwoTypos = 10
}
};

await client.Index("mvoies").UpdateTypoToleranceAsync(typoTolerance);
settings_guide_typo_tolerance_1: |-
var typoTolerance = new TypoTolerance {
DisableOnAttributes = new string[] { "title" },
MinWordSizeTypos = new TypoTolerance.TypoSize {
TwoTypos = 12
}
};

await client.Index("mvoies").UpdateTypoToleranceAsync(typoTolerance);
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ JSON Output:

## 🤖 Compatibility with Meilisearch

This package only guarantees the compatibility with the [version v0.26.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.26.0).
This package only guarantees the compatibility with the [version v0.27.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.27.0).

## 🎬 Examples

Expand Down
40 changes: 40 additions & 0 deletions src/Meilisearch/Index.cs
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,46 @@ public async Task<TaskInfo> ResetSynonymsAsync(CancellationToken cancellationTok
return await httpresponse.Content.ReadFromJsonAsync<TaskInfo>(cancellationToken: cancellationToken).ConfigureAwait(false);
}

/// <summary>
/// Gets the typo tolerance setting.
/// </summary>
/// <param name="cancellationToken">The cancellation token for this call.</param>
/// <returns>Returns the typo tolerance setting.</returns>
public async Task<TypoTolerance> GetTypoToleranceAsync(CancellationToken cancellationToken = default)
{
return await _http.GetFromJsonAsync<TypoTolerance>($"indexes/{Uid}/settings/typo-tolerance", cancellationToken: cancellationToken)
.ConfigureAwait(false);
}

/// <summary>
/// Updates the typo tolerance setting.
/// </summary>
/// <param name="typoTolerance">TypoTolerance instance</param>
/// <param name="cancellationToken">The cancellation token for this call.</param>
/// <returns>Returns the task info of the asynchronous task.</returns>
public async Task<TaskInfo> UpdateTypoToleranceAsync(TypoTolerance typoTolerance, CancellationToken cancellationToken = default)
{
var responseMessage =
await _http.PostAsJsonAsync($"indexes/{Uid}/settings/typo-tolerance", typoTolerance, Constants.JsonSerializerOptionsRemoveNulls, cancellationToken: cancellationToken)
.ConfigureAwait(false);

return await responseMessage.Content.ReadFromJsonAsync<TaskInfo>(cancellationToken: cancellationToken)
.ConfigureAwait(false);
}

/// <summary>
/// Resets the typo tolerance setting.
/// </summary>
/// <param name="cancellationToken">The cancellation token for this call.</param>
/// <returns>Returns the task info of the asynchronous task.</returns>
public async Task<TaskInfo> ResetTypoToleranceAsync(CancellationToken cancellationToken = default)
{
var response = await _http.DeleteAsync($"indexes/{Uid}/settings/typo-tolerance", cancellationToken)
.ConfigureAwait(false);

return await response.Content.ReadFromJsonAsync<TaskInfo>(cancellationToken: cancellationToken).ConfigureAwait(false);
}

/// <summary>
/// Get stats.
/// </summary>
Expand Down
18 changes: 18 additions & 0 deletions src/Meilisearch/SearchQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,24 @@ public class SearchQuery
[JsonPropertyName("attributesToHighlight")]
public IEnumerable<string> AttributesToHighlight { get; set; }

/// <summary>
/// Gets or sets the crop marker to apply before and/or after cropped part selected within an attribute defined in `attributesToCrop` parameter.
/// </summary>
[JsonPropertyName("cropMarker")]
public string CropMarker { get; set; }

/// <summary>
/// Gets or sets the tag to put before the highlighted query terms.
/// </summary>
[JsonPropertyName("highlightPreTag")]
public string HighlightPreTag { get; set; }

/// <summary>
/// Gets or sets the tag to put after the highlighted query terms.
/// </summary>
[JsonPropertyName("highlightPostTag")]
public string HighlightPostTag { get; set; }

/// <summary>
/// Gets or sets the facets distribution for the query.
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions src/Meilisearch/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,11 @@ public class Settings
/// </summary>
[JsonPropertyName("sortableAttributes")]
public IEnumerable<string> SortableAttributes { get; set; }

/// <summary>
/// Gets or sets the typo tolerance attributes.
/// </summary>
[JsonPropertyName("typoTolerance")]
public TypoTolerance TypoTolerance { get; set; }
}
}
50 changes: 50 additions & 0 deletions src/Meilisearch/TypoTolerance.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace Meilisearch
{
/// <summary>
/// Typo Tolerance configuration.
/// </summary>
public class TypoTolerance
{
/// <summary>
/// Whether the typo tolerance feature is enabled
/// </summary>
[JsonPropertyName("enabled")]
public bool Enabled { get; set; }

/// <summary>
/// Disable the typo tolerance feature on the specified document attributes.
/// </summary>
[JsonPropertyName("disableOnAttributes")]
public IEnumerable<string> DisableOnAttributes { get; set; }

/// <summary>
/// Disable the typo tolerance feature for a given set of terms in a search query.
/// </summary>
[JsonPropertyName("disableOnWords")]
public IEnumerable<string> DisableOnWords { get; set; }

/// <summary>
/// Customize the minimum word size to tolerate typos.
/// </summary>
[JsonPropertyName("minWordSizeForTypos")]
public TypoSize MinWordSizeForTypos { get; set; }

public class TypoSize
{
/// <summary>
/// Customize the minimum word size to tolerate 1 typo.
/// </summary>
[JsonPropertyName("oneTypo")]
public int? OneTypo { get; set; }

/// <summary>
/// Customize the minimum word size to tolerate 2 typos.
/// </summary>
[JsonPropertyName("twoTypos")]
public int? TwoTypos { get; set; }
}
}
}
60 changes: 60 additions & 0 deletions tests/Meilisearch.Tests/IndexFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,66 @@ public async Task<Index> SetUpIndexForFaceting(string indexUid)
return index;
}

public async Task<Index> SetUpIndexForNestedSearch(string indexUid)
{
var index = DefaultClient.Index(indexUid);
var movies = new[]
{
new MovieWithInfo
{
Id = "10",
Name = "Gladiator",
Info = new MovieInfo { Comment = "a movie about old times", ReviewNb = 700 }
},
new MovieWithInfo
{
Id = "11",
Name = "Interstellar",
Info = new MovieInfo { Comment = "the best movie", ReviewNb = 1000 }
},
new MovieWithInfo
{
Id = "12",
Name = "Star Wars",
Info = new MovieInfo { Comment = "a lot of wars in the stars", ReviewNb = 900 }
},
new MovieWithInfo
{
Id = "13",
Name = "Harry Potter",
Info = new MovieInfo { Comment = "a movie about a wizard boy", ReviewNb = 900 }
},
new MovieWithInfo
{
Id = "14",
Name = "Iron Man",
Info = new MovieInfo { Comment = "a movie about a rich man", ReviewNb = 800 }
},
new MovieWithInfo
{
Id = "15",
Name = "Spider-Man",
Info = new MovieInfo { Comment = "the spider bit the boy", ReviewNb = 900 }
},
new MovieWithInfo
{
Id = "16",
Name = "Amélie Poulain",
Info = new MovieInfo { Comment = "talks about hapiness", ReviewNb = 800 }
},
};
var task = await index.AddDocumentsAsync(movies);

// Check the documents have been added
var finishedTask = await index.WaitForTaskAsync(task.Uid);
if (finishedTask.Status != "succeeded")
{
throw new Exception("The documents were not added during SetUpIndexForNestedSearch. Impossible to run the tests.");
}

return index;
}

public async Task DeleteAllIndexes()
{
var indexes = await DefaultClient.GetAllIndexesAsync();
Expand Down
17 changes: 17 additions & 0 deletions tests/Meilisearch.Tests/Movie.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@ public class Movie
public string Genre { get; set; }
}

public class MovieInfo
{
public string Comment { get; set; }

public int ReviewNb { get; set; }
}

public class MovieWithInfo
{
public string Id { get; set; }

public string Name { get; set; }

public MovieInfo Info { get; set; }
}


public class MovieWithIntId
{
public int Id { get; set; }
Expand Down
85 changes: 85 additions & 0 deletions tests/Meilisearch.Tests/SearchTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace Meilisearch.Tests
public abstract class SearchTests<TFixture> : IAsyncLifetime where TFixture : IndexFixture
{
private Index _basicIndex;
private Index _nestedIndex;
private Index _indexForFaceting;
private Index _indexWithIntId;

Expand All @@ -26,6 +27,7 @@ public async Task InitializeAsync()
_basicIndex = await _fixture.SetUpBasicIndex("BasicIndex-SearchTests");
_indexForFaceting = await _fixture.SetUpIndexForFaceting("IndexForFaceting-SearchTests");
_indexWithIntId = await _fixture.SetUpBasicIndexWithIntId("IndexWithIntId-SearchTests");
_nestedIndex = await _fixture.SetUpIndexForNestedSearch("IndexForNestedDocs-SearchTests");
}

public Task DisposeAsync() => Task.CompletedTask;
Expand Down Expand Up @@ -311,5 +313,88 @@ public async Task CustomSearchWithSort()
Assert.Equal(2, movies.Hits.Count());
Assert.Equal("14", movies.Hits.First().Id);
}

[Fact]
public async Task CustomSearchWithCroppingParameters()
{
var movies = await _basicIndex.SearchAsync<FormattedMovie>(
"man",
new SearchQuery { CropLength = 1, AttributesToCrop = new string[] { "*" } }
);

Assert.NotEmpty(movies.Hits);
Assert.Equal("…Man", movies.Hits.First()._Formatted.Name);
}

[Fact]
public async Task CustomSearchWithCropMarker()
{
var movies = await _basicIndex.SearchAsync<FormattedMovie>(
"man",
new SearchQuery { CropLength = 1, AttributesToCrop = new string[] { "*" }, CropMarker = "[…] " }
);

Assert.NotEmpty(movies.Hits);
Assert.Equal("[…] Man", movies.Hits.First()._Formatted.Name);
}

[Fact]
public async Task CustomSearchWithCustomHighlightTags()
{
var movies = await _basicIndex.SearchAsync<FormattedMovie>(
"man",
new SearchQuery
{
AttributesToHighlight = new string[] { "*" },
HighlightPreTag = "<mark>",
HighlightPostTag = "</mark>"
}
);

Assert.NotEmpty(movies.Hits);
Assert.Equal("Iron <mark>Man</mark>", movies.Hits.First()._Formatted.Name);
}

[Fact]
public async Task CustomSearchWithinNestedDocuments()
{
var movies = await _nestedIndex.SearchAsync<MovieWithInfo>("wizard");

Assert.NotEmpty(movies.Hits);
Assert.Equal("Harry Potter", movies.Hits.First().Name);
Assert.Equal("13", movies.Hits.First().Id);
Assert.Equal("a movie about a wizard boy", movies.Hits.First().Info.Comment);
}

[Fact]
public async Task CustomSearchWithinNestedDocumentsWithSearchableAttributesSettings()
{
var task = await _nestedIndex.UpdateSearchableAttributesAsync(new string[] { "name", "info.comment" });
await _nestedIndex.WaitForTaskAsync(task.Uid);

var movies = await _nestedIndex.SearchAsync<MovieWithInfo>("rich");

Assert.NotEmpty(movies.Hits);
Assert.Equal("Iron Man", movies.Hits.First().Name);
Assert.Equal("14", movies.Hits.First().Id);
Assert.Equal("a movie about a rich man", movies.Hits.First().Info.Comment);
}

[Fact]
public async Task CustomSearchWithinNestedDocumentsWithSearchableAndSortableAttributesSettings()
{
var searchTask = await _nestedIndex.UpdateSearchableAttributesAsync(new string[] { "name", "info.comment" });
await _nestedIndex.WaitForTaskAsync(searchTask.Uid);
var sortTask = await _nestedIndex.UpdateSortableAttributesAsync(new string[] { "info.reviewNb" });
await _nestedIndex.WaitForTaskAsync(sortTask.Uid);

var query = new SearchQuery { Sort = new string[] { "info.reviewNb:desc" } };
var movies = await _nestedIndex.SearchAsync<MovieWithInfo>("", query);

Assert.NotEmpty(movies.Hits);
Assert.Equal("Interstellar", movies.Hits.First().Name);
Assert.Equal("11", movies.Hits.First().Id);
Assert.Equal(1000, movies.Hits.First().Info.ReviewNb);
}
}
}
Loading