Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Use the simple dictionary in full text search for the user directory (#…
Browse files Browse the repository at this point in the history
…8959)

* Use the simple dictionary in fts for the user directory

* Clarify naming
  • Loading branch information
babolivier authored Dec 17, 2020
1 parent c070223 commit f2783fc
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 12 deletions.
1 change: 1 addition & 0 deletions changelog.d/8959.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug causing common English words to not be considered for a user directory search.
24 changes: 12 additions & 12 deletions synapse/storage/databases/main/user_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,9 +396,9 @@ def _update_profile_in_user_dir_txn(txn):
sql = """
INSERT INTO user_directory_search(user_id, vector)
VALUES (?,
setweight(to_tsvector('english', ?), 'A')
|| setweight(to_tsvector('english', ?), 'D')
|| setweight(to_tsvector('english', COALESCE(?, '')), 'B')
setweight(to_tsvector('simple', ?), 'A')
|| setweight(to_tsvector('simple', ?), 'D')
|| setweight(to_tsvector('simple', COALESCE(?, '')), 'B')
) ON CONFLICT (user_id) DO UPDATE SET vector=EXCLUDED.vector
"""
txn.execute(
Expand All @@ -418,9 +418,9 @@ def _update_profile_in_user_dir_txn(txn):
sql = """
INSERT INTO user_directory_search(user_id, vector)
VALUES (?,
setweight(to_tsvector('english', ?), 'A')
|| setweight(to_tsvector('english', ?), 'D')
|| setweight(to_tsvector('english', COALESCE(?, '')), 'B')
setweight(to_tsvector('simple', ?), 'A')
|| setweight(to_tsvector('simple', ?), 'D')
|| setweight(to_tsvector('simple', COALESCE(?, '')), 'B')
)
"""
txn.execute(
Expand All @@ -435,9 +435,9 @@ def _update_profile_in_user_dir_txn(txn):
elif new_entry is False:
sql = """
UPDATE user_directory_search
SET vector = setweight(to_tsvector('english', ?), 'A')
|| setweight(to_tsvector('english', ?), 'D')
|| setweight(to_tsvector('english', COALESCE(?, '')), 'B')
SET vector = setweight(to_tsvector('simple', ?), 'A')
|| setweight(to_tsvector('simple', ?), 'D')
|| setweight(to_tsvector('simple', COALESCE(?, '')), 'B')
WHERE user_id = ?
"""
txn.execute(
Expand Down Expand Up @@ -764,7 +764,7 @@ async def search_user_dir(self, user_id, search_term, limit):
INNER JOIN user_directory AS d USING (user_id)
WHERE
%s
AND vector @@ to_tsquery('english', ?)
AND vector @@ to_tsquery('simple', ?)
ORDER BY
(CASE WHEN d.user_id IS NOT NULL THEN 4.0 ELSE 1.0 END)
* (CASE WHEN display_name IS NOT NULL THEN 1.2 ELSE 1.0 END)
Expand All @@ -773,13 +773,13 @@ async def search_user_dir(self, user_id, search_term, limit):
3 * ts_rank_cd(
'{0.1, 0.1, 0.9, 1.0}',
vector,
to_tsquery('english', ?),
to_tsquery('simple', ?),
8
)
+ ts_rank_cd(
'{0.1, 0.1, 0.9, 1.0}',
vector,
to_tsquery('english', ?),
to_tsquery('simple', ?),
8
)
)
Expand Down
23 changes: 23 additions & 0 deletions tests/storage/test_user_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
ALICE = "@alice:a"
BOB = "@bob:b"
BOBBY = "@bobby:a"
# The localpart isn't 'Bela' on purpose so we can test looking up display names.
BELA = "@somenickname:a"


class UserDirectoryStoreTestCase(unittest.TestCase):
Expand All @@ -40,6 +42,9 @@ def setUp(self):
yield defer.ensureDeferred(
self.store.update_profile_in_user_dir(BOBBY, "bobby", None)
)
yield defer.ensureDeferred(
self.store.update_profile_in_user_dir(BELA, "Bela", None)
)
yield defer.ensureDeferred(
self.store.add_users_in_public_rooms("!room:id", (ALICE, BOB))
)
Expand Down Expand Up @@ -72,3 +77,21 @@ def test_search_user_dir_all_users(self):
)
finally:
self.hs.config.user_directory_search_all_users = False

@defer.inlineCallbacks
def test_search_user_dir_stop_words(self):
"""Tests that a user can look up another user by searching for the start if its
display name even if that name happens to be a common English word that would
usually be ignored in full text searches.
"""
self.hs.config.user_directory_search_all_users = True
try:
r = yield defer.ensureDeferred(self.store.search_user_dir(ALICE, "be", 10))
self.assertFalse(r["limited"])
self.assertEqual(1, len(r["results"]))
self.assertDictEqual(
r["results"][0],
{"user_id": BELA, "display_name": "Bela", "avatar_url": None},
)
finally:
self.hs.config.user_directory_search_all_users = False

0 comments on commit f2783fc

Please sign in to comment.