Skip to content

Default to 'and' operator for match queries. Remove slug search, prioritize exact matches more.#7303

Merged
EnTeQuAk merged 28 commits into
masterfrom
and-search-operator
Jan 30, 2018
Merged

Default to 'and' operator for match queries. Remove slug search, prioritize exact matches more.#7303
EnTeQuAk merged 28 commits into
masterfrom
and-search-operator

Conversation

@EnTeQuAk

@EnTeQuAk EnTeQuAk commented Jan 15, 2018

Copy link
Copy Markdown
Contributor
  • prioritize a match on name.raw higher by moving it up in the rules list
  • Add operator: and to non fuzzy match queries, this doesn't do anything to match_phrase but this should already improve matching quite a bit
  • Removed keyword filtering from legacy search api, e.g "delicious platform:mac" doesn't work anymore.
  • Added a new flag "search-use-dfs-query-then-fetch" to make use of support for dfs-query-then-fetch search type: https://www.elastic.co/blog/understanding-query-then-fetch-vs-dfs-query-then-fetch
  • Made sure we only have one shard during testing to make our search-scoring tests more predictable

References many "component: search" issues. What I tested with a
database of all public add-ons:

Example searches:

  • tab center redux - should find "Tab Center Redux" while "Tab Mix Plus" is probably second and "Redux DevTools" 4th or so
  • Open Image in New Tab -> should find "Open Image in New Tab" while "Open Bookmarks in New Tab" should be 2nd or 3rd
  • CoinHive -> Finds "Coinhive Blocker", "CoinBlock" (prefix search) and "NoMiners" (description)
  • Privacy -> Finds "Privacy Badger", "Privacy Pass", "Privacy Settings", "Google Privacy" (probably 4th or so) and "Blur" (summary + description + many users). Scores "Ghostery" on the first page but ranks it in the middle
  • firebu -> Finds "Firebug", "Firebug Autocompleter", "Firefinder for Firebug"
  • fireb -> Scores "Fire Drag" first, puts "Firebug" approximately 3rd or so
  • Menu Wizzard -> Finds "Menu Wizard" (fuzzy, typo) first, then "Add-ons Manager Context Menu" apparently because it matches good in the title and has many users
  • Frame Demolition -> Finds "Frame Demolition"
  • Demolition -> Finds only "Frame Demolition", same for "Demolation" (typo)
    reStyle -> Finds "reStyle" and scores a few add-ons that match on "restore" next since the term is similar
  • MegaUpload DownloadHelper -> finds "MegaUpload DownloadHelper" first, scores "Video * DownloadHelper" and "RadpidShare DownloadHelper" next. Doesn't find "Popup Blocker" anymore as currently happening on -prod
  • MegaUpload -> only finds "MegaUpload DownloadHelper" and nothing else
  • No Flash -> Scores "No Flash" first, then depending on users "Download Flash and Video", "YouTube Flash Video Player" and "YouTube Flash Player" (not necessarily in that order)
    Disable Hello, Pocket & Reader+ -> finds "Disable Hello, Pocket & Reader+" first (yeay!), then scores "Reader", "Disable WebRTC" and "In My Pocket" next similarly to what's happening on -prod currently

Please note that these are more "Guidelines", actual results in production may differ depending on shard configuration and document spreading. We might want to think about using https://www.elastic.co/guide/en/elasticsearch/reference/master/search-request-search-type.html#dfs-query-then-fetch which doesn't sound too bad imho, might hurt performance though. One step at a time.

Not working yet:

Not sure if it's specifically only because of these changes but mozilla/addons#3378 is fixed.

This potentially fixes mozilla/addons#5141, mozilla/addons#5004, mozilla/addons#4977, mozilla/addons#4778, mozilla/addons#359.

Not sure if this fixes mozilla/addons#567 but the results look much more promising and the amount of results doesn't explode here. I only have 2.8k add-ons for testing though so I'm not too sure.

And might be relevant to mozilla/addons#4652.

This is a big step towards mozilla/addons#3097, I doubt we can call this fixed though.

Script used to download public add-ons locally and test above searches: https://gist.github.com/EnTeQuAk/7f74c3018466bbffbaa4427842a451f8

As a next step we could try making the (query.Match, {'query': search_query, 'boost': 3, 'standard', 'operator': 'and'}) part a must instead of linking it all together with a should. But that's just a random thought.

…ritize exact matches more.

References many "component: search" issues. What I tested with a
database of all public add-ons:

Example searches:

tab center redux - should find "Tab Center Redux" while "Tab Mix Plus" is probably second and "Redux DevTools" 4th or so
Open Image in New Tab -> should find "Open Image in New Tab" while "Open Bookmarks in New Tab" should be 2nd or 3rd
CoinHive -> Finds "Coinhive Blocker", "CoinBlock" (prefix search) and "NoMiners" (description)
Privacy -> Finds "Privacy Badger", "Privacy Pass", "Privacy Settings", "Google Privacy" (probably 4th or so) and "Blur" (summary + description + many users). Scores "Ghostery" on the first page but ranks it in the middle
firebu -> Finds "Firebug", "Firebug Autocompleter", "Firefinder for Firebug"
fireb -> Scores "Fire Drag" first, puts "Firebug" approximately 3rd or so
Menu Wizzard -> Finds "Menu Wizard" (fuzzy, typo) first, then "Add-ons Manager Context Menu" apparently because it matches good in the title and has many users
Frame Demolition -> Finds "Frame Demolition"
Demolition -> Finds only "Frame Demolition", same for "Demolation" (typo)
reStyle -> Finds "reStyle" and scores a few add-ons that match on "restore" next since the term is similar
MegaUpload DownloadHelper -> finds "MegaUpload DownloadHelper" first, scores "Video DownloadHelper" and "RadpidShare DownloadHelper" next. Doesn't find "Popup Blocker" anymore as currently happening on -prod
MegaUpload -> only finds "MegaUpload DownloadHelper" and nothing else
No Flash -> Scores "No Flash" first, then depending on users "Download Flash and Video", "YouTube Flash Video Player" and "YouTube Flash Player" (not necessarily in that order)
Disable Hello, Pocket & Reader+ -> finds "Disable Hello, Pocket & Reader+" first (yeay!), then scores "Reader", "Disable WebRTC" and "In My Pocket" next similarly to what's happening on -prod currently

Not working yet:

privacybadger -> "Privacy Badger" -> will probably need some kind of ngram filtering and analyzing (#591)
eyes -> 'decentraleyes' -> Not sure this should actually work, will probably need some more analyzing too (#591)

Not sure if it's specifically only because of these changes but #3248 is fixed.

This potentially fixes #7244, #6891, #6837, #6417, mozilla/addons#359.

Not sure if this fixes #mozilla/addons#567 but the results look much more promising and the amount of results doesn't explode here. I only have 2.8k add-ons for testing though so I'm not too sure.

And might be relevant to #6137.

This is a big step towards #2661, I doubt we can call this fixed though.
@EnTeQuAk EnTeQuAk requested a review from diox January 15, 2018 18:23
@EnTeQuAk

Copy link
Copy Markdown
Contributor Author

Note: I'm working on figuring out that legacy api test failure, looks kinda weird since the actual problem is that for some reason GrApple Yummy isn't found when searching for grapple. Might be some analyzing or something weird since it works in master. Still investigating.

@eviljeff

Copy link
Copy Markdown
Member

What's the argument in favour of merging this without unittests? It's not a large changeset currently - is one of the issues a particularly urgent fix?

@diox

diox commented Jan 16, 2018

Copy link
Copy Markdown
Member

I'm with @eviljeff : I don't think it's particularly urgent, so we should wait for tests (well they are broken currently so we have to wait anyway). Just a simple search view test proving that all the words are now used vs only a few should be enough.

PS: why removing the slug? The rest of the changes seem to make sense at first glance.

@EnTeQuAk

Copy link
Copy Markdown
Contributor Author

Alrighty, I'll spare some more time then and work on proper tests. I'll try to update the PR tomorrow (Wed) and see how that goes.

@EnTeQuAk

Copy link
Copy Markdown
Contributor Author

PS: why removing the slug? The rest of the changes seem to make sense at first glance.

There were more than a handful scenarios where removing the slug immensely improved the overall scoring. As we already discussed some time ago I still believe that searching on the slug might not be the best idea since it's more or less one word for ElasticSearch right now with some fancy punctuation in there. Sometimes it's even truncated. It sure messes up fuzzy searches on which we rely quite a bit.

I can try to write some more tests to prove that though, this is mainly from the search-scenarios above and a few other tests.

@diox

diox commented Jan 16, 2018

Copy link
Copy Markdown
Member

There were more than a handful scenarios where removing the slug immensely improved the overall scoring. As we already discussed some time ago I still believe that searching on the slug might not be the best idea since it's more or less one word for ElasticSearch right now with some fancy punctuation in there. Sometimes it's even truncated. It sure messes up fuzzy searches on which we rely quite a bit.

I can try to write some more tests to prove that though, this is mainly from the search-scenarios above and a few other tests.

That explanation is enough for me. Maybe add a comment somewhere so that we're not tempted to add it back?

@EnTeQuAk

EnTeQuAk commented Jan 16, 2018 via email

Copy link
Copy Markdown
Contributor Author

@EnTeQuAk

Copy link
Copy Markdown
Contributor Author

Alrighty, I added tests and re-configured our test settings to only have one replica and one shard to make the scoring more reliable.

Alternatively we might want to think about using https://www.elastic.co/guide/en/elasticsearch/reference/master/search-request-search-type.html#dfs-query-then-fetch which doesn't sound too bad imho, might hurt performance though.

@EnTeQuAk

Copy link
Copy Markdown
Contributor Author

FYI: There are a few TODOs in some tests still, I'd like to get them work more incrementally and focus on the big picture first maybe, some are obscure but should work eventually.

I'll also squash this before merging, I usually don't like squashing while in a pull request

view.request = self.request
qset = view.get_queryset()

return qset.filter('term', id=self.addon.pk).execute()[0]

@diox diox Jan 29, 2018

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit : we use qs pretty much everywhere. Applies to a lot of other parts below.

@diox diox left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

self.request,
'search-use-dfs-query-then-fetch')
if dfs_query_then_fetch:
qset = qset.params(search_type='dfs_query_then_fetch')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand why you're doing this after reading ES doc, but it deserves a comment.

name='Amazon 1-Click Lock', type=amo.ADDON_EXTENSION,
average_daily_users=50, weekly_downloads=0),

cls.refresh()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An improvement for later: prevent the individual index calls while you're adding all these add-ons, then call reindex instead of refresh.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, I'll add it to my list of future improvements and will open an issue about it


def test_scenario_megaupload(self):
self._check_scenario('MegaUpload', (
# I have litterally NO idea :-/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add TODO :)


def test_scenario_no_flash(self):
# TODO: Doesn't put "No Flash" on first line, does the "No"
# do something special here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no is a stopword FWIW

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true but the "no idea" part comes where we have a raw term match and IMHO (correct me if I'm wrong) that raw term match should not make use of any analyzing, stopword filtering etc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Try and switch to AND default search operator for search queries Two search terms narrows the results; three search terms explodes them.

3 participants