Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Pleroma
pleroma
Commits
ed8f55ab
Commit
ed8f55ab
authored
Jan 18, 2019
by
Ivan Tashkinov
Browse files
[
#477
] User: FTS and trigram search results mixing (to handle misspelled requests).
parent
0bc6d30f
Changes
3
Show whitespace changes
Inline
Side-by-side
lib/pleroma/user.ex
View file @
ed8f55ab
...
@@ -679,13 +679,35 @@ def get_recipients_from_activity(%Activity{recipients: to}) do
...
@@ -679,13 +679,35 @@ def get_recipients_from_activity(%Activity{recipients: to}) do
end
end
def
search
(
query
,
resolve
\\
false
,
for_user
\\
nil
)
do
def
search
(
query
,
resolve
\\
false
,
for_user
\\
nil
)
do
#
s
trip the beginning @ off if there is a query
#
S
trip the beginning @ off if there is a query
query
=
String
.
trim_leading
(
query
,
"@"
)
query
=
String
.
trim_leading
(
query
,
"@"
)
if
resolve
do
if
resolve
,
do
:
User
.
get_or_fetch_by_nickname
(
query
)
User
.
get_or_fetch_by_nickname
(
query
)
fts_results
=
do_search
(
fts_search_subquery
(
query
),
for_user
)
trigram_results
=
do_search
(
trigram_search_subquery
(
query
),
for_user
)
Enum
.
uniq_by
(
fts_results
++
trigram_results
,
&
&1
.
id
)
end
end
defp
do_search
(
subquery
,
for_user
,
options
\\
[])
do
q
=
from
(
s
in
subquery
(
subquery
),
order_by:
[
desc:
s
.
search_rank
],
limit:
^
(
options
[
:limit
]
||
20
)
)
results
=
q
|>
Repo
.
all
()
|>
Enum
.
filter
(
&
(
&1
.
search_rank
>
0
))
boost_search_results
(
results
,
for_user
)
end
defp
fts_search_subquery
(
query
)
do
processed_query
=
processed_query
=
query
query
|>
String
.
replace
(
~r/\W+/
,
" "
)
|>
String
.
replace
(
~r/\W+/
,
" "
)
...
@@ -694,7 +716,6 @@ def search(query, resolve \\ false, for_user \\ nil) do
...
@@ -694,7 +716,6 @@ def search(query, resolve \\ false, for_user \\ nil) do
|>
Enum
.
map
(
&
(
&1
<>
":*"
))
|>
Enum
.
map
(
&
(
&1
<>
":*"
))
|>
Enum
.
join
(
" | "
)
|>
Enum
.
join
(
" | "
)
inner
=
from
(
from
(
u
in
User
,
u
in
User
,
select_merge:
%{
select_merge:
%{
...
@@ -715,21 +736,27 @@ def search(query, resolve \\ false, for_user \\ nil) do
...
@@ -715,21 +736,27 @@ def search(query, resolve \\ false, for_user \\ nil) do
},
},
where:
not
is_nil
(
u
.
nickname
)
where:
not
is_nil
(
u
.
nickname
)
)
)
end
q
=
defp
trigram_search_subquery
(
query
)
do
from
(
from
(
s
in
subquery
(
inner
),
u
in
User
,
order_by:
[
desc:
s
.
search_rank
],
select_merge:
%{
limit:
20
search_rank:
fragment
(
"similarity(?, ? || ' ' || coalesce(?, ''))"
,
^
query
,
u
.
nickname
,
u
.
name
)
},
where:
not
is_nil
(
u
.
nickname
)
)
)
end
results
=
defp
boost_search_results
(
results
,
nil
),
do
:
results
q
|>
Repo
.
all
()
|>
Enum
.
filter
(
&
(
&1
.
search_rank
>
0
))
weighted_results
=
defp
boost_search_results
(
results
,
for_user
)
do
if
for_user
do
friends_ids
=
get_friends_ids
(
for_user
)
friends_ids
=
get_friends_ids
(
for_user
)
followers_ids
=
get_followers_ids
(
for_user
)
followers_ids
=
get_followers_ids
(
for_user
)
...
@@ -752,11 +779,6 @@ def search(query, resolve \\ false, for_user \\ nil) do
...
@@ -752,11 +779,6 @@ def search(query, resolve \\ false, for_user \\ nil) do
end
end
)
)
|>
Enum
.
sort_by
(
&
(
-
&1
.
search_rank
))
|>
Enum
.
sort_by
(
&
(
-
&1
.
search_rank
))
else
results
end
weighted_results
end
end
def
blocks_import
(%
User
{}
=
blocker
,
blocked_identifiers
)
when
is_list
(
blocked_identifiers
)
do
def
blocks_import
(%
User
{}
=
blocker
,
blocked_identifiers
)
when
is_list
(
blocked_identifiers
)
do
...
...
test/user_test.exs
View file @
ed8f55ab
...
@@ -814,6 +814,12 @@ test "finds users, ranking by similarity" do
...
@@ -814,6 +814,12 @@ test "finds users, ranking by similarity" do
assert
[
u4
.
id
,
u3
.
id
,
u1
.
id
]
==
Enum
.
map
(
User
.
search
(
"lain@ple"
),
&
&1
.
id
)
assert
[
u4
.
id
,
u3
.
id
,
u1
.
id
]
==
Enum
.
map
(
User
.
search
(
"lain@ple"
),
&
&1
.
id
)
end
end
test
"finds users, handling misspelled requests"
do
u1
=
insert
(
:user
,
%{
name:
"lain"
})
assert
[
u1
.
id
]
==
Enum
.
map
(
User
.
search
(
"laiin"
),
&
&1
.
id
)
end
test
"finds users, boosting ranks of friends and followers"
do
test
"finds users, boosting ranks of friends and followers"
do
u1
=
insert
(
:user
)
u1
=
insert
(
:user
)
u2
=
insert
(
:user
,
%{
name:
"Doe"
})
u2
=
insert
(
:user
,
%{
name:
"Doe"
})
...
...
test/web/twitter_api/twitter_api_controller_test.exs
View file @
ed8f55ab
...
@@ -1656,7 +1656,7 @@ test "it denies a friend request" do
...
@@ -1656,7 +1656,7 @@ test "it denies a friend request" do
test
"it returns users, ordered by similarity"
,
%{
conn:
conn
}
do
test
"it returns users, ordered by similarity"
,
%{
conn:
conn
}
do
user
=
insert
(
:user
,
%{
name:
"eal"
})
user
=
insert
(
:user
,
%{
name:
"eal"
})
user_two
=
insert
(
:user
,
%{
name:
"eal me"
})
user_two
=
insert
(
:user
,
%{
name:
"eal me"
})
_user_three
=
insert
(
:user
,
%{
name:
"
ebn
"
})
_user_three
=
insert
(
:user
,
%{
name:
"
zzz
"
})
resp
=
resp
=
conn
conn
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment