-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extend accounts table for custom search attributes #27832
Conversation
Steps:
Expected: guest user appears
|
note that in my case the email address also started with "someone". Well, actually I used "Vincent" as guest name and "[email protected]" (where hostname.tld is the local computer) when testing. So the bug could also be related to this overlap when searching. From the error it seems to be an API issue. |
d24b379
to
dccd8c2
Compare
REF: #27850 |
lib/private/User/Backend.php
Outdated
@@ -46,6 +46,7 @@ | |||
const SET_DISPLAYNAME = 1048576; // 1 << 20 | |||
const PROVIDE_AVATAR = 16777216; // 1 << 24 | |||
const COUNT_USERS = 268435456; // 1 << 28 | |||
const SEARCH_STRING = 4294967296; // 1 << 32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we start exceeding max int here ... why are the constants shifted by 4 anyway? wtf?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👽
$table->addColumn('searchString', 'string', [ | ||
'notnull' => false, | ||
'length' => 64, | ||
]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs an index
49e24c9
to
8e00ed3
Compare
$qb->select('*') | ||
->from($this->getTableName()) | ||
->where($qb->expr()->Like('user_id', $qb->createNamedParameter('%' . $this->db->escapeLikeParameter(strtolower($pattern)) . '%'))) | ||
->orWhere($qb->expr()->iLike('display_name', $qb->createNamedParameter('%' . $this->db->escapeLikeParameter($pattern) . '%'))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quoting comment from http://stackoverflow.com/a/34029944:
It is in PostgreSQL the keyword ILIKE can be used instead of LIKE to make the match case-insensitive according to the active locale. This is not in the SQL standard but is a PostgreSQL extension.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we have hidden magic then it's ok.
lib/private/Group/Manager.php
Outdated
foreach($groupUsers as $groupUser) { | ||
$matchingUsers[$groupUser->getUID()] = $groupUser; | ||
} | ||
die(var_dump($matchingUsers)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💣 💥
// Add column to hold additional search attributes | ||
$table->addColumn('search_attributes', 'string', [ | ||
'notnull' => false, | ||
'length' => 64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is far from being enough
802798c
to
80a4a7d
Compare
80a4a7d
to
9d75572
Compare
26a5275
to
5ebc7bc
Compare
]); | ||
|
||
// Add index for search attributes | ||
$table->addIndex(['search_attributes'], 'search_attributes_index'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need a combined index if one query searches in multiple columns
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tomneedham any update ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope. we need an index per or part of a query:
-- with combined index
CREATE INDEX find_index ON oc_accounts (lower_user_id, display_name, email);
sqlite> EXPLAIN QUERY PLAN select * from oc_accounts WHERE lower_user_id LIKE '%test%' and display_name LIKE '%test%' and email LIKE '%test%';
0|0|0|SCAN TABLE oc_accounts
sqlite> EXPLAIN QUERY PLAN select * from oc_accounts WHERE lower_user_id LIKE '%test%' or display_name LIKE '%test%' or email LIKE '%test%';
0|0|0|SCAN TABLE oc_accounts
sqlite> EXPLAIN QUERY PLAN select * from oc_accounts WHERE lower_user_id LIKE '%test%' or display_name LIKE '%test%' or email LIKE '%test%';
0|0|0|SCAN TABLE oc_accounts
sqlite> EXPLAIN QUERY PLAN select * from oc_accounts WHERE lower_user_id = '%test%' or display_name = '%test%' or email = '%test%';
0|0|0|SCAN TABLE oc_accounts
sqlite> EXPLAIN QUERY PLAN select * from oc_accounts WHERE lower_user_id = '%test%' and display_name = '%test%' and email = '%test%';
0|0|0|SEARCH TABLE oc_accounts USING INDEX find_index (lower_user_id=? AND display_name=? AND email=?)
sqlite>
...
-- with individual indexes
CREATE UNIQUE INDEX lower_user_id_index ON oc_accounts (lower_user_id);
CREATE INDEX display_name_index ON oc_accounts (display_name);
CREATE INDEX email_index ON oc_accounts (email);
sqlite> EXPLAIN QUERY PLAN select * from oc_accounts WHERE lower_user_id = '%test%' and display_name = '%test%' and email = '%test%';
0|0|0|SEARCH TABLE oc_accounts USING INDEX lower_user_id_index (lower_user_id=?)
sqlite> EXPLAIN QUERY PLAN select * from oc_accounts WHERE lower_user_id = '%test%' or display_name = '%test%' or email = '%test%';
0|0|0|SEARCH TABLE oc_accounts USING INDEX lower_user_id_index (lower_user_id=?)
0|0|0|SEARCH TABLE oc_accounts USING INDEX display_name_index (display_name=?)
0|0|0|SEARCH TABLE oc_accounts USING INDEX email_index (email=?)
sqlite>
then again like kills the indexes on sqlite anyway:
EXPLAIN QUERY PLAN select * from oc_accounts WHERE lower_user_id like '%test%' or display_name like '%test%' or email like '%test%';
0|0|0|SCAN TABLE oc_accounts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh well. the %test%
like comparison kills the index on all dbms. If we use test%
it is much better:
mysql> explain select * from oc_accounts WHERE lower_user_id like '%test%' or display_name like '%test%' or email like '%test%';
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | oc_accounts | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where |
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
mysql> explain select * from oc_accounts WHERE lower_user_id like 'test%' or display_name like 'test%' or email like 'test%';
+----+-------------+-------------+------------+------+----------------------------------------------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+------+----------------------------------------------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | oc_accounts | NULL | ALL | lower_user_id_index,display_name_index,email_index | NULL | NULL | NULL | 1 | 100.00 | Using where |
+----+-------------+-------------+------------+------+----------------------------------------------------+------+---------+------+------+----------+-------------+
sqlite never seems to use an index for like
mysql can use separate indexes as well as a combined index ... if we don't do medial searches.
for ldap we have 'user_ldap.enable_medial_search'
in config.php to allow medial searches. we could do the same for sql. say ... 'accounts.enable_medial_search'
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok guest app part seems to work again |
With the guest app if I type in the email of the previously created guest user it appears in the list with the display name and I can select it for sharing. |
Fixes #27847 |
Apart from the index question, is this ready ? @butonic @DeepDiver1975 @jvillafanez |
wait, im testing now :) |
Looks good for me now 👍 Tested and works! |
185 for the length of the search_attributes column as according to some research by @butonic this is the max indexable length we can achieve - so my understanding is that if we add an index that spans this column as well it won't be effective |
Working on a new branch / PR - closing for now |
the new PR #27906 |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Description
How Has This Been Tested?
Types of changes
Checklist: