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

Add 'fullyHighlighted', 'matchLevel' and 'matchedWords' to '_highlightResult' in autocomplete client #1337

Open
sgilberg opened this issue Oct 29, 2024 · 4 comments · Fixed by #1347 · May be fixed by #1359
Open

Add 'fullyHighlighted', 'matchLevel' and 'matchedWords' to '_highlightResult' in autocomplete client #1337

sgilberg opened this issue Oct 29, 2024 · 4 comments · Fixed by #1347 · May be fixed by #1359
Assignees
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@sgilberg
Copy link

Description
In the hits returned from getAlgoliaResults, the _highlightResult object includes not just the value of the attribute but also three properties that help to interpret the match: fullyHighlighted, matchLevel, and matchedWords. The getMeilisearchResults hits, in contrast, only include the value. I would like to request the addition of the other three values, if at all possible.

Basic example
We are attempting to migrate from Algolia to Meilisearch, but this is a sticking point for us. A real-world example where these properties come into play is one we have frequently: an index of entities that each have a primary name and an array of synonyms, both of which are searchable attributes. In the autocomplete results display, we would like to show just the highlighted name if it is a full match, and if not, we add on the best-matched synonym (showing a fully-highlighted synonym match if one is found, a synonym with matchLevel: full if not, and finally the synonym with the most matched words if no full match level is available).

Here's a real example of what this looks like for us using Algolia's results (showing only the templates definition here for brevity):

templates: {
    item({ item, components, html}) {
        if (item._highlightResult.full_name.matchLevel !== 'full' && item._highlightResult.synonyms) {
            var synonym_match = item._highlightResult.synonyms.find(function(synonym) {
                return synonym.matchLevel === 'full' && synonym.fullyHighlighted;
            });
            if (synonym_match === undefined) {
                synonym_match = item._highlightResult.synonyms.find(function(synonym) {
                    return synonym.matchLevel === 'full';
                });
                if (synonym_match === undefined && item._highlightResult.full_name.matchLevel === 'none') {
                    var synonyms = item._highlightResult.synonyms.filter(function (synonym) {
                        return synonym.matchLevel !== 'none';
                    }).sort(function (a, b) {
                        return b.matchedWords.length - a.matchedWords.length;
                    });
                    synonym_match = synonyms[0];
                }
            }
            if (synonym_match !== undefined) {
                synonym_match._highlightResult = { // Workaround to get the highlight component to work (bonus points if you can improve upon Algolia's current default)
                    name: {
                        value: synonym_match.value
                    }
                };
                return html`<span>${components.Highlight({
                    hit: item,
                    attribute: 'full_name',
                })} <span class="text-muted">- synonym match: ${components.Highlight({
                    hit: synonym_match,
                    attribute: 'name',
                })}</span></span>`;
            }
        }

        return html`<span>${components.Highlight({
            hit: item,
            attribute: 'full_name',
        })}</span>`;
    },
},
@Strift
Copy link
Collaborator

Strift commented Dec 19, 2024

Hello @sgilberg, thanks for opening an issue.

This seems like a welcome addition for the autocomplete client. I will start taking a look at this :)

@meili-bors meili-bors bot closed this as completed in 8d9409b Dec 27, 2024
@Strift
Copy link
Collaborator

Strift commented Dec 27, 2024

Hey, I released a new version that includes the highlights metadata. Let me know if it works for you :)

@sgilberg
Copy link
Author

sgilberg commented Jan 2, 2025

Hi @Strift thank you so much for working on this! This is partly working for me, and partly not. It works pretty well for attributes that are one-to-one, and for nested arrays that don't have keys, but I'm getting errors on indexes that have nested arrays with keys (even if those arrays aren't searchable attributes).

Here's an example record to illustrate what I mean:

{
   "id": 1,
   "name": "Joseph",
   "nicknames": [
      "Joe",
      "Joey"
   ],
   "family_members": [
       {
           "relationship": "mother",
           "name": "Susan"
       },
       {
           "relationship": "father",
           "name": "John"
       }
   ]
}

In the above, the "family_members" style of data breaks the integration ("Cannot read properties of undefined (reading 'replace')" at calculateHighlightMetadata). Indexes that only have fields like id, name, or nicknames work fine.

I think there might be two parts to the issue: one is that these highlight calculations seem to be done on all fields, regardless of whether they are meant to be searchable or highlighted or not, which at best is overkill and at worst might impact performance or cause errors as in my case. The other is that, in cases where such data should be searchable, we'd want that calculation to work on those nested properties too.

For what it's worth I also notice that the match level full vs partial seems to be case dependent, and I'm not sure if that's intentional (or if it's consistent with Algolia's behavior, I'd need to dig in on that). E.g. for the example record above if I search "joseph" it will show as partial but if I search "Joseph" it is full.

@Strift Strift reopened this Jan 8, 2025
@Strift Strift added the help wanted Extra attention is needed label Jan 15, 2025
@Strift
Copy link
Collaborator

Strift commented Jan 15, 2025

Hey, I managed to get it working for the basic cases, but I want to make the logic smart enough to handle recursive scenarios. But I'm not sure if it will actually be relevant.

@meilisearch/product-team How deep in objects, arrays, or arrays of objects on average do customers have "searchable" fields? If you can share some insights with me, it would allow me to prioritize this better. Thanks 🙏

@Strift Strift linked a pull request Jan 15, 2025 that will close this issue
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
2 participants