How to display the matched words of an Algolia search query?

你说的曾经没有我的故事 提交于 2019-12-11 02:25:37

问题


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, as attributesToIndex, but can also be overridden at query time (and can only contain attributes also in attributesToIndex)
  • 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 than attributesToHighlight.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!