heywhy / ex_elasticlunr

Elasticlunr is a small, full-text search library for use in the Elixir environment. It indexes JSON documents and provides a friendly search interface to retrieve documents.
https://hexdocs.pm/elasticlunr
MIT License
189 stars 9 forks source link

Can't get query-time boosting to work #22

Open doughsay opened 1 year ago

doughsay commented 1 year ago

Hey, I like the promise of this library, but can't barely get anything to work, and the lack of any documentation makes it very hard to figure out how to use it properly. I do not have previous elastic/lucene experience, so it's very difficult trying to trial-and-error queries.

Here's my scenario, I have an index:

pipeline = Pipeline.new(Pipeline.default_runners())

[pipeline: pipeline]
|> Index.new()
|> Index.add_field("name", )
|> Index.add_field("author_names")
|> Index.add_field("author_person_names")
|> Index.add_field("narrator_names")
|> Index.add_field("narrator_person_names")
|> Index.add_field("series_names")

And I want to search for a query string in all the fields but with various weights. Here are two patterns I've tried, neither of them work:

# in this example, "expand" is being honored, but "boost" is not:
Elasticlunr.Index.search(index, %{
  "query" => %{
    "bool" => %{
      "should" => [
        %{"match" => %{"name" => %{"boost" => 1.0, "query" => query, "expand" => true}}},
        %{"match" => %{"author_names" => %{"boost" => 0.5, "query" => query, "expand" => true}}},
        %{"match" => %{"author_person_names" => %{"boost" => 0.25, "query" => query, "expand" => true}}},
        %{"match" => %{"narrator_names" => %{"boost" => 0.5, "query" => query, "expand" => true}}},
        %{"match" => %{"narrator_person_names" => %{"boost" => 0.25, "query" => query, "expand" => true}}},
        %{"match" => %{"series_names" => %{"boost" => 0.5, "query" => query, "expand" => true}}}
      ]
    }
  }
})

# This example seems to be what the library expects based on reading the source code but there are bugs preventing this from working:
Elasticlunr.Index.search(index, query, %{
  "fields" => %{
    "name" => %{"boost" => 1.0},
    "author_names" => %{"boost" => 0.5},
    "author_person_names" => %{"boost" => 0.25},
    "narrator_names" => %{"boost" => 0.5},
    "narrator_person_names" => %{"boost" => 1.0},
    "series_names" => %{"boost" => 0.25},
  }
})

Regarding the second example above, there are some obvious errors in the code. See here: https://github.com/heywhy/ex_elasticlunr/blob/master/lib/elasticlunr/core/index.ex#L203 you are iterating over a map here, but expecting the field string to be given to the callback, when in fact it's a {field_name, value} tuple. It seems there are no high-level tests in the library to catch this error.

Please let me know if this is even something that should be possible, or if I'm barking up the wrong tree.