Ich versuche, einen Teilindex Postgresql Jsonb Spalte hinzufügen. Die jsonb-Spalte heißt: email_provider. Ich habe versucht, einen Teilindex auf der Spalte wie unten gezeigt hinzuzufügen, aber es wirft anderen Fehler wie dieses PG :: UndefinedColumn: FEHLER: Spalte "email_povider" existiert nicht und zu anderen Zeiten wirft es den Fehler an: PG :: AmbiguousFunction : ERROR: Betreiber ist nicht eindeutig: unbekannt -> unbekanntErstellen Sie Partial-Index für Postgresql Jsonb-Feld
der Teilindex in der Schienen-5 Migration wie folgt aussieht:
add_index :accounts, :name, name: "index_accounts_on_email_provider_kind", using: :gin, where: "('email_provider' -> 'sparkpost' ->> 'smtp_host' = 'www.sparkpost.com') AND ('email_povider' -> 'amazon ses' ->> 'smtp_host' = 'www.awses.com')"
die json für die email_provider Spalte sieht wie folgt aus:
{
"email_provider": {
"sparkpost": {
"smtp_host": "www.sparkpost.com",
"smtp_port": ""
},
"aws ses": {
"smtp_host": "www.amazon/ses.com ",
"smtp_port": " ",
"username": " ",
"password": " "
}
}
}
Die Tabelle sieht wie folgt aus:
class CreateAccounts < ActiveRecord::Migration[5.0]
def change
create_table :accounts do |t|
t.string :name, null: false
t.jsonb :email_provider, null: false
t.jsonb :social_account, default: '[]', null: false
t.timestamps
end
add_index :accounts, :name, name: "index_accounts_on_email_provider_kind", using: :gin, where: "('email_provider' -> 'sparkpost' ->> 'smtp_host' = 'www.sparkpost.com') AND ('email_povider' -> 'amazon ses' ->> 'smtp_host' = 'www.awses.com')"
add_index :accounts, :name, name: "index_accounts_on_social_account_type", using: :gin, where: " 'social_account' @> [{'type': 'facebook'}] AND 'social_account' @> [{'type': 'twitter'}]"
end
end
aktualisieren
Basierend auf leichte Anpassung an die akzeptierte Antwort unten, der Code, den ich btree nicht Gin Index erstellen bin mit in Schienen wird Activrecord unten gezeigt. Es schafft einen btree Index, weil wir die Namensspalte verwenden, die von String-Datentyp ist und nicht jsonb als here beschrieben:
add_index :accounts, :name, name: "index_accounts_on_name_email_provider", where: "email_provider -> 'sparkpost' ->> 'smtp_host' = 'www.sparkpost.com' AND email_provider -> 'amazon ses' ->> 'smtp_host' = 'www.awses.com' "
add_index :accounts, :name, name: "index_accounts_on_name_social_account", where: " social_account @> '[{\"type\": \"facebook\"}]'::jsonb AND social_account @> '[{\"type\": \"twitter\"}]'::jsonb"
Danke, ich werde das ausprobieren und auf Sie zurückkommen. Aber ich werde höchstwahrscheinlich den Index auf die Spalte ** name ** setzen, obwohl die Spalte jsonb ** email provider ** ist, weil die Abfrage schneller ist, wenn der Index in der Spalte ** name ** und dem ** steht. Dabei wird query ** verwendet, um unseren Index auf Treffer aus der jsonb-Spalte zu beschränken. Sie können diesen Ansatz hier erklärt sehen: http://blog.heapanalytics.com/speeding-up-postgresql-queries-with-partial-indexes/. – brg
Vielen Dank. Ich habe den Index in der Spalte ** Name ** beibehalten. Die einzige Änderung war, ** mit:: gin ** zu entfernen, da der Index nicht direkt in der jsonb-Spalte steht. Der endgültige Code für einen der Indizes sieht dann wie folgt aus: ** add_index: accounts,: name, name: "index_accounts_on_name_email_provider", wobei: "(email_provider -> 'email_provider' -> 'sparkpost' - >> 'smtp_host' = ' www.sparkpost.com ') AND (email_provider ->' email_povider '->' amazon ses '- >>' smtp_host '=' www.awses.com ') "**, was einen ** btree partiellen Index ** erzeugt in der Spalte ** name **, die unsere Übereinstimmungen auf Attribute in der jsonb-Spalte beschränkt. – brg