-
Notifications
You must be signed in to change notification settings - Fork 58
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
Using _Formatted value when searching is not user friendly #315
Comments
I just checked the rust client for this issue, I'm no expert but according to the doc : This works thanks to serde, who has the ability to flatten structs. The unit tests in Java are passing because the In C# we saw, that we create an index with a The way the response is sent actually does not play well with strongly type languages. In C# and Java, the unit tests are not really well shaped, in rust this works because of the flattening feature of serde. I think, everything is here about this issue. |
Thank you, @juchom, for your research and this very well-detailed issue.
Indeed, we want 0 breaking changes to not involve any significant and tedious changes until 1.0, especially on the search endpoint. Nevertheless, this is something we may consider after having reached a v1.0. We know that we will have to make some breaking changes afterward, but it's unclear how we will organize all this to be the most convenient for the users and us in terms of management. We are working on it to elaborate strategies to handle this type of change in the future. |
@juchom, thanks for the issue. Indeed very well explained, and I could feel the pain here 😞 Do you think it could be possible to work around this problem internally in the return await responseMessage.Content
.ReadFromJsonAsync<SearchResult<T>>(cancellationToken: cancellationToken).ConfigureAwait(false); |
Good question ? Very good question... Digging further, I found this issue opened in Not sure this is going to happen soon and there is nothing that could help with it on Github. We only have bad solutions right now, The worst one, trying to create our own public class SearchResult<T>
{
[JsonPropertyFlatten]
public T Result { get; set; }
[JsonPropertyName("_formatted")]
public T FormattedResult { get; set; }
} Writing this, just made me realised, that the rust client is already patching the json response to map to the proposed json response thanks to serde's flatten attribute. Second option, bad developer experience but it would work without side effect if we use custom json options write a clear documentation on how to deal with it. In my case I'm going to wrap everything where needed and create the second class by hand. // My indexed object
public class Movie
{
public string Id { get; set; }
public string Name { get; set; }
public string Genre { get; set; }
}
// The search result class, a bit like the unit tests, but we keep refactoring tools working
public class MovieSearchResult : Movie
{
[JsonPropertyName("_formatted")]
public Movie Formatted { get; set; }
} Maybe a source generator could help doing this second class automatically for the developer, but I have never used them before and I'm not sure it would be good idea to offer this option if it works. (Andrew Lock has a very good blog about them : https://andrewlock.net/creating-a-source-generator-part-1-creating-an-incremental-source-generator/) In my case I don't have a bunch of documents so doing it by hand is ok, but for people with bigger projects source generators is probably the best bet. Concerning Java, I think code generators exist but I have no idea of what we can do. There are some project on github to flatten json objects, but it seems that it's not following the same pattern like serde. In my case I want to be extra safe, I would go with writing a second inherited class and let Concerning Meilisearch server, here is the response object : /// A single result.
/// Contains the complete object, optionally the formatted object, and optionally an object that contains information about the matches.
#[derive(Deserialize, Debug)]
pub struct SearchResult<T> {
/// The full result.
#[serde(flatten)]
pub result: T,
/// The formatted result.
#[serde(rename = "_formatted")]
pub formatted_result: Option<Map<String, Value>>,
/// The object that contains information about the matches.
#[serde(rename = "_matchesPosition")]
pub matches_position: Option<HashMap<String, Vec<MatchRange>>>,
} Without I would encourage you to think twice before using Just to be clear, there is no arrogance in my last sentence, I have been caught in this trap once it was a GUID serialization / deserialization issue between Python and C#. And again your are doing a really good job and Meilisearch is a really great product 👍 |
Thanks @juchom ! Came across this caveat and could immediately workaround it with your approach. |
As the SDK does not support highlights, maybe the readme should mention it? It even gives an example using |
For me it works fine, I got highlighting in all "attrA", "attrB", "attrC". var myIndexSettings = new Settings
{
DisplayedAttributes = new string[] { "*" },
SearchableAttributes = new string[] { "attrA", "attrB", "attrC" },
};
var result = await Index.SearchAsync<MyType>(
queryString,
new SearchQuery()
{
AttributesToHighlight = new string[] { "attrA", "attrB", "attrC" }, // will be returned formatted
AttributesToCrop = new string[] { "attrC" }, // will be returned formatted
HighlightPreTag = "<mark>",
HighlightPostTag = "</mark>",
CropLength = 60,
},
cancellationToken: cancellationToken
); |
That is weird. Is that on the master build, or the currently released NuGet build? If I call it with |
Did you implement juchom's solution with the search result class that inherits from the actual type you have an index for? |
No, that’s my whole point, that it’s not supported out of the box. |
@Christoph-Wagner that's right, it's not supported directly because there is no clean strategy to support this json transformation made server side. This issue has been discovered after the api freeze this is why it works like this for now and you have to chose what best fit your needs. Now that v1 is out, maybe @gmourier or @brunoocasali may have some insight on this issue. |
@juchom Recently while working on the meilisearch flutter ui kit, I tried an approach, where we wrapped all the returned results from meilisearch with a helper object that would understand all the extra fields added by meilisearch and parse them correctly. class MeilisearchResultContainer<T> {
final T parsed;
final Map<String, dynamic> src;
final Map<String, dynamic>? formatted;
final Searcheable<Map<String, Object?>> fromResult;
final SearchQuery fromQuery;
MeilisearchResultContainer({
required this.src,
required this.parsed,
required this.fromQuery,
required this.fromResult,
}) : formatted = src['_formatted'];
} it would also reference the source query and the parent search result, but these can be omitted of course. this made handling meilisearch specific fields way easier |
If the product team decide to keep the original object without transformation and make this change soon, then I think it will be better to wait. Otherwise, it will be probably wise to use your work and provide a solution that makes dotnet devs life easier. |
I can safely state that a v2 is not in our current plans. And also, the same behavior is being used in other features like the new vector store feature ( So I think if the implementation made by @ahmednfwela is good enough, we should definitely merge it :) Then in the future, when Meilisearch starts to plan a possible v2, we can decide to go for a Are you ok with that @juchom and @ahmednfwela? |
528: Implements show ranking scores in search query r=curquiza a=massijay # Pull Request ## Related issue Fixes #458 ## What does this PR do? - Implements show ranking scores in search query - Does not implement a user friendly way to retrieve the score in the response (impossible to do without making breaking changes, see also #315, #426) users have to add the field in their classes themselves ## PR checklist Please check if your PR fulfills the following requirements: - [x] Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)? - [x] Have you read the contributing guidelines? - [x] Have you made sure that the title is accurate and descriptive of the changes? Thank you so much for contributing to Meilisearch! Co-authored-by: Massimiliano Cristarella <[email protected]> Co-authored-by: Massimiliano Cristarella <[email protected]> Co-authored-by: Clémentine U. - curqui <[email protected]>
I have the same issue. Any updates on this? There are workarounds to fix it, but as other people mentioned, the |
Hello @MoienTajik |
While I was working on the code I saw something that is not user friendly for C# and Java developers.
If you look at the documentation for Highlighting : https://docs.meilisearch.com/reference/api/search.html#attributes-to-highlight
Here is the json response of the server :
The server returns the document and add an extra field
_formatted
with a modified copy of the document.Let see the problem now with C#:
We're going to work with this unit test :
meilisearch-dotnet/tests/Meilisearch.Tests/SearchTests.cs
Lines 76 to 94 in 3302d2b
We are working on the
_basicIndex
and here is the definition of it :meilisearch-dotnet/tests/Meilisearch.Tests/IndexFixture.cs
Lines 46 to 69 in 3302d2b
We are adding a collection of
Movie
and here is the definition :meilisearch-dotnet/tests/Meilisearch.Tests/Movie.cs
Lines 3 to 10 in 3302d2b
Now, on line 86 of the test we are doing a Search query against Meilisearch with this code :
We are querying an index that contains
Movie
documents, but we ask to map to another classFormattedMovie
with this definition :meilisearch-dotnet/tests/Meilisearch.Tests/Movie.cs
Lines 38 to 48 in 3302d2b
We have to duplicate the
Movie
class with aFormattedMovie
class in order to have the_Formatted
property available.This is not very user friendly, because users will have to create two objects in order to fully use Meilisearch.
There is no way in C# to create a specific object that will enhance a base object with a
_Formatted
property like this :There is actually also a small risk of collision if a document contains a
_formatted
property.I told Guillaume it would great to have a response with an
original
andformatted
properties that contains both a version of the document.One more interesting thing in having a response like the one above is that if you want to add extra information like the global score of this result, or a score per field, you could enhance it easily without any risk of fields collisions.
But it's too late for breaking changes. So we need to find a way for developers (C# / Java) to enjoy this feature without too much pain.
Ping @gmourier @brunoocasali
The text was updated successfully, but these errors were encountered: