问题
I'm using Algolia's algoliasearch-client-js and autocomplete.js to power searches on my website. That works.
But I also want to include the excerpt/snippet of the text with which the search query matches. How to do that?
My current code is:
autocomplete('#search-input', { hint: true, autoselect: true }, [
{
source: autocomplete.sources.hits(index, { hitsPerPage: 7 }),
displayKey: 'title',
templates: {
footer: '<span class="search-foot">Powered by <a href="https://www.algolia.com/" target="_blank" title="Algolia - Hosted cloud search as a service"><img src="/static/assets/algolia-logo.png" width="47" height="15"></a></span>',
suggestion: function(suggestion) {
return '<div class="search-lang">' +
suggestion._highlightResult.platform.value +
'</div>' +
suggestion._highlightResult.title.value;
}
}
}
]).on('autocomplete:selected', function(event, suggestion, dataset) {
window.location.href = suggestion.url;
});
To highlight the excerpt that caused the query to match with a record, their FAQ says:
The AttributesToSnippet setting is a way to shorten ("snippet") your long chunks of text to display them in the search results. Just think about the small pieces of text displayed below a Google result: it's built from a subset of the sentences of the page content, includes your matching keywords, and avoid flooding the search results page. For example, if you limit the number of words of the "description" attribute to 10, the "_snippetResult.description.value" attribute of the JSON answer will only contain the 10 best words of this description.
There's no example of AttributesToSnippet
, however. On their Github documentation I find a bit more info:
attributesToHighlight
- scope: settings, search
- type: array of strings
- default: null
Default list of attributes to highlight. If set to null, all indexed attributes are highlighted.
A string that contains the list of attributes you want to highlight according to the query. Attributes are separated by commas. You can also use a string array encoding (for example ["name","address"]). If an attribute has no match for the query, the raw value is returned. By default, all indexed attributes are highlighted (as long as they are strings). You can use * if you want to highlight all attributes.
I'm struggling with translating their abstract, scattered information into a coherent piece of code. Any suggestions?
回答1:
attributesToIndex
, attributesToHighlight
and attributesToSnippet
are the three main settings used for highlighting.
- attributesToIndex is an index setting (you can set it in your dashboard or your back-end, but not in the front-end).
- attributesToHighlight are, if not set, equal to the
attributesToIndex
. They can be set in your index settings, asattributesToIndex
, but can also be overridden at query time (and can only contain attributes also inattributesToIndex
) - attributesToSnippet are, if not set, equal to an empty array. Each attribute can have a modifier at the end like
:10
to say how much words you want in your snippet. Other than that, they work the same way thanattributesToHighlight
.
Let's take an example:
Index settings
attributesToIndex: ['title', 'description']
attributesToHighlight: ['title']
attributesToSnippet: ['description:3']
Record
{
"title": "Test article",
"description": "A long long long test description long long long",
"link": "https://test.com/test-article"
}
For the query "test"
, here's basically the JSON of a suggestion you'd get:
{
"title": "Test article",
"description": "A long long long test description long long long",
"link": "https://test.com/test-article",
"_highlightResult": {
"title": {
"value": "<em>Test article</em>"
}
},
"_snippetResult": {
"description": {
"value": "... long <em>test</em> description ..."
}
}
}
Notice that neither description
nor link
are in the _highlightResult
object.link
was ignored from the search since it's not in the attributesToIndex
description
is not in the _highlightResult
because it's not in attributesToHighlight
.
You can also notice that in both _highlightResult
and _snippetResult
, the test
word is wrapped in <em></em>
tags. That's the tags you can use to show which words matched.
I've omitted some attributes of the answer that didn't help understand my answer. You can see them in your browser console by adding a small console.log(suggestion)
at the beginning of your suggestion function.
回答2:
I've fixed the problem myself, due to finding a setting in Algolia's dashboard by pure luck. To make the returned search results return the snippet too, I did two things:
1). There's an option in Algolia's dashboard that's named 'Attributes to snippet', which you can find in the 'Display' tab of the particular index that you're searching with.
In my case, I set that option to the record attribute that I wanted to highlight in my search queries like this:
2). After I configured that setting, I could access _snippetResult
in the function for the autocomplete.js library. As you can see in the image above, the attribute that I added to the 'Attributes to snippet' option was 'content', and so I access the words that matched with the search query with suggestion._snippetResult.content.value
.
My code now is:
autocomplete('#search-input', { hint: true, autoselect: false }, [
{
source: autocomplete.sources.hits(index, { hitsPerPage: 7 }),
displayKey: 'title',
templates: {
footer: '<span class="search-foot">Powered by <a href="https://www.algolia.com/" target="_blank" title="Algolia - Hosted cloud search as a service"><img src="/static/assets/algolia-logo.png" width="47" height="15"></a></span>',
suggestion: function(suggestion) {
return '<div class="search-lang">' +
suggestion._highlightResult.platform.value +
'</div><div class="search-title">' +
suggestion._highlightResult.title.value +
'</div>' + '<div class="search-snippet">' +
suggestion._snippetResult.content.value + '</div>';
}
}
}
]).on('autocomplete:selected', function(event, suggestion, dataset) {
window.location.href = suggestion.url;
});
So to summarise, there is simply a manual option to enable the return of search snippets instead of having to use attributesToSnippet
somewhere in the code.
来源:https://stackoverflow.com/questions/40042909/how-to-display-the-matched-words-of-an-algolia-search-query