Search code examples
searchrankingfacetalgoliascoring

Algolia: Search across multiple fields and scoring results


I have the following task to achieve in algolia

Context

I have the following recordset in my index

[
    {
        "name" : "Don Joe",
        "experience": {
          "job_title": "Example 1",
          "superpowers": [
            "Golang", // <- MATCH (see below)
            "Vue",    // <- MATCH (see below)
            "React"
          ],
          "skills": [
            "Docker",
            "Goa",
            "Elixir",
            "Kubernetes",
            "Istio",
            "Phoenix",
            "Javascript"
          ]
      },
      "completed_at": 1590509228,
    },
    {
        "name" : "John Doe"
        "experience": {
          "job_title": "Example 2",
          "superpowers": [
            "Golang", // <- MATCH (see below)
            "Phoenix",
            "React"
          ],
          "skills": [
            "Docker",
            "Vue",    // <- MATCH (see below)
            "Kubernetes",
            "Elixir",
            "Goa",
            "Javascript",
            "Typescript"
          ]
      },
      "completed_at": 1590519361,
    }
]

The searchable attributes are set as

  • unordered(experience.superpowers)
  • unordered(experience.skills)

The ranking is the default one, plus

  • custom ranking desc(completed_at)

What I do

A simple textual search Golang Vue

What I expect

Superpowers have priority over skills, so since "Don Joe" has Golang and Vue in his superpowers ( while "John Doe" has Golang superpower and Vue skill) should appear first

What happens instead

The 2 records have the same score, and tie-breaking algorithm brings up the wrong one (which is not the main issue here, the issue is they have same score in first place)

Any idea in how I should configure algolia to perform what I expect?

Thanks in advance


Solution

  • Solution

    I solved as follows:

    1. Convert a textual search to a "facets based" search
    2. Set up experience.skills and experience.superpowers to be facets
    3. use a series of OR filters with scores to get the desired facets
      {
         "filters": "experience.skills:Vue<score=1> OR experience.skills:Golang<score=1> OR experience.superpowers:Vue<score=2> OR experience.superpowers:Golang<score=2>",
         "sumOrFiltersScores": true 
      }
      
      IMPORTANT: set "sumOrFiltersScores": true to enable sum of scores and use a weighted search
    4. Call your search method using the payload in previous step.

    Resources:

    https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/in-depth/filter-scoring/