Индекс массива на ArangoDb

Моя коллекция в ArangoDb имеет объекты с этой схемой (упрощенной):

{
 "userName": "Billy",
 "email": "[removed_email]",
 "logins": [
 {
 "authenticationTokens": [],
 "loginProvider": "Facebook",
 "providerKey": "123",
 "providerDisplayName": null
 }
 ],
 "roles": [],
 "claims": []
}

Эта реализация ASPNetCore.Identity на ArangoDb by BorderEast aspnetcore-identity-arangodb

ПРОБЛЕМА:

Чтобы использовать Facebook, он использует запрос AQL

for u in IdentityUser for l in u.logins filter l.loginProvider == "Facebook" && l.providerKey == "123" return u

который работает хорошо, но не использует какой-либо индекс

Indexes used:
 none

Я пробовал индексы:

db.IdentityUser.ensureIndex({ type: "hash", fields: [ "logins[*].loginProvider", "logins[*].providerKey" ] });
db.IdentityUser.ensureIndex({ type: "hash", fields: [ "logins[*].loginProvider" ] });
db.IdentityUser.ensureIndex({ type: "hash", fields: [ "logins[*].providerKey" ], unique: true });

Ни один из них не используется.

Может ли кто-нибудь сообщить, как должен выглядеть индекс для этого запроса?

1 ответ

Проблема заключается в их запросе. Его нужно переписать, и тогда он будет работать. Это связано с использованием in оператора сравнения, как обсуждалось в этом ответе:

"Тем не менее запрос в 2.8 не будет использовать этот индекс, потому что индексы массива используются только для оператора сравнения IN".

Поэтому, если мы изменим запрос, мы получим следующее:

Query string:
 for u in IdentityUser 
 let l = u.logins[*].loginProvider
 let p = u.logins[*].providerKey
 filter "google" in l and "googlekey" in p
 return u

Execution plan:
 Id NodeType Est. Comment
 1 SingletonNode 1 * ROOT
 8 IndexNode 1 - FOR u IN IdentityUser /* persistent index scan */
 9 CalculationNode 1 - LET #7 = ("googlekey" in u.'logins'[*].'providerKey') /* simple expression */ /* collections used: u : IdentityUser */
 6 FilterNode 1 - FILTER #7
 7 ReturnNode 1 - RETURN u

Indexes used:
 By Type Collection Unique Sparse Selectivity Fields Ranges
 8 persistent IdentityUser false false n/a [ 'logins[*].loginProvider' ] ("google" in u.'logins'[*].'loginProvider')

Optimization rules applied:
 Id RuleName
 1 move-calculations-up
 2 remove-unnecessary-calculations
 3 use-indexes
 4 remove-filter-covered-by-index

licensed under cc by-sa 3.0 with attribution.