diff --git a/docker-compose.yml b/docker-compose.yml index 410b55e..03cc49f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,8 @@ services: PGUSER: *pguser PGPASSWORD: *pgpass PGDATABASE: *pgdb + + WANIKANI_API_KEY: # required to cache to database in advance ports: - 5433:5432 # pgAdmin connection port diff --git a/initdb.d/01-function.sql b/initdb.d/01-function.sql index 42db199..2c6e7e1 100755 --- a/initdb.d/01-function.sql +++ b/initdb.d/01-function.sql @@ -24,3 +24,8 @@ CREATE OR REPLACE FUNCTION identity (JSONB) RETURNS JSONB AS $func$ SELECT $1; $func$ LANGUAGE SQL IMMUTABLE; + +CREATE OR REPLACE FUNCTION identity (TEXT) RETURNS TEXT AS +$func$ +SELECT $1; +$func$ LANGUAGE SQL IMMUTABLE; diff --git a/initdb.d/10-wanikani.sql b/initdb.d/10-wanikani.sql index d001036..f277306 100755 --- a/initdb.d/10-wanikani.sql +++ b/initdb.d/10-wanikani.sql @@ -17,6 +17,10 @@ CREATE TABLE "wanikani.subjects" ( ); CREATE INDEX "idx_wanikani.subjects_object" ON "wanikani.subjects" ("object"); + +CREATE INDEX "idx_wanikani.subjects_data-characters" ON "wanikani.subjects" (("data" ->> 'characters')); +CREATE INDEX "idx_wanikani.subjects_data-level" ON "wanikani.subjects" ((("data" -> 'level')::int)); + CREATE INDEX "idx_wanikani.subjects_data" ON "wanikani.subjects" USING pgroonga("data") WITH ( @@ -29,3 +33,32 @@ CREATE INDEX "idx_wanikani.subjects_data_kana" ON "wanikani.subjects" tokenizer='TokenMecab', normalizer='NormalizerNFKC100("unify_kana", true)' ); + +CREATE MATERIALIZED VIEW "wanikani.subjects.sentences" AS ( + SELECT + (s ->> 'ja') "ja", + (s ->> 'en') "en" + FROM "wanikani.subjects", jsonb_array_elements("data" -> 'context_sentences') "s" + WHERE s ->> 'ja' > '' +); + +CREATE INDEX "idx_wanikani.subjects.sentences_ja" ON "wanikani.subjects.sentences" + USING pgroonga("ja") + WITH ( + tokenizer='TokenMecab', + normalizer='NormalizerNFKC100("unify_kana", true)' + ); + +CREATE INDEX "idx_wanikani.subjects.sentences_ja_kana" ON "wanikani.subjects.sentences" + USING pgroonga((identity("ja"))) + WITH ( + tokenizer='TokenMecab("use_reading", true)', + normalizer='NormalizerNFKC100("unify_kana", true)' + ); + +CREATE INDEX "idx_wanikani.subjects.sentences_en" ON "wanikani.subjects.sentences" + USING pgroonga("en") + WITH ( + plugins='token_filters/stem', + token_filters='TokenFilterStem' + ); diff --git a/initdb.d/22-entry.sql b/initdb.d/22-entry.sql index 5fcaf77..6ed8a91 100755 --- a/initdb.d/22-entry.sql +++ b/initdb.d/22-entry.sql @@ -4,6 +4,10 @@ CREATE TABLE "entry" ( "updatedAt" TIMESTAMPTZ DEFAULT now(), "userId" UUID NOT NULL REFERENCES "user"("id") ON DELETE CASCADE, "type" TEXT NOT NULL, + "_type" TEXT[] GENERATED ALWAYS AS (CASE + WHEN "type" = 'character' THEN ARRAY['character', 'hanzi', 'kanji'] + ELSE ARRAY["type"] + END) STORED, "entry" TEXT[] NOT NULL CHECK ("entry"[1] IS NOT NULL), "reading" JSONB NOT NULL DEFAULT '{}', -- TODO: jsonschema "translation" JSONB NOT NULL DEFAULT '{}', -- TODO: jsonschema @@ -11,9 +15,14 @@ CREATE TABLE "entry" ( "tag" TEXT[] NOT NULL DEFAULT '{}', "level" FLOAT, "level.kanji" INT, - "frequency" FLOAT, "key" TEXT UNIQUE, "_meta" JSONB, -- TODO: jsonschema + "priority" INT GENERATED ALWAYS AS (CASE + WHEN "type" = 'vocabulary' THEN 10 + WHEN "type" = 'character' THEN 5 + WHEN "type" = 'sentence' THEN 1 + ELSE 0 + END) STORED, PRIMARY KEY ("id") ); @@ -22,12 +31,13 @@ CREATE TRIGGER "t_entry_updatedAt" FOR EACH ROW EXECUTE PROCEDURE "f_updatedAt"(); +CREATE INDEX "idx_entry_priority" ON "entry" ("priority"); + CREATE INDEX "idx_entry_updatedAt" ON "entry" ("updatedAt"); CREATE INDEX "idx_entry_userId" ON "entry" ("userId"); -CREATE INDEX "idx_entry_type" ON "entry" ("type"); +CREATE INDEX "idx_entry_type" ON "entry" USING GIN("_type"); CREATE INDEX "idx_entry_level" ON "entry" ("level"); CREATE INDEX "idx_entry_level.kanji" ON "entry" ("level.kanji"); -CREATE INDEX "idx_entry_frequency" ON "entry" ("frequency"); CREATE INDEX "idx_entry_description" ON "entry" USING pgroonga("description") diff --git a/initdb.d/24-preset.sql b/initdb.d/24-preset.sql index 0b3f93c..7a4590c 100755 --- a/initdb.d/24-preset.sql +++ b/initdb.d/24-preset.sql @@ -1,4 +1,4 @@ -CREATE TABLE "preset.quiz" ( +CREATE TABLE "quiz.preset" ( "id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMPTZ DEFAULT now(), "updatedAt" TIMESTAMPTZ DEFAULT now(), @@ -7,12 +7,12 @@ CREATE TABLE "preset.quiz" ( "settings" JSONB NOT NULL ); -CREATE TRIGGER "t_preset.quiz_updatedAt" - BEFORE UPDATE ON "preset.quiz" +CREATE TRIGGER "t_quiz.preset_updatedAt" + BEFORE UPDATE ON "quiz.preset" FOR EACH ROW EXECUTE PROCEDURE "f_updatedAt"(); -CREATE INDEX "idx_preset.quiz_updatedAt" ON "preset.quiz" ("updatedAt"); -CREATE INDEX "idx_preset.quiz_userId" ON "preset.quiz" ("userId"); -CREATE INDEX "idx_preset.quiz_name" ON "preset.quiz" +CREATE INDEX "idx_quiz.preset_updatedAt" ON "quiz.preset" ("updatedAt"); +CREATE INDEX "idx_quiz.preset_userId" ON "quiz.preset" ("userId"); +CREATE INDEX "idx_quiz.preset_name" ON "quiz.preset" USING pgroonga ("name"); diff --git a/initdb.d/27-freq.sql b/initdb.d/27-freq.sql index 6212051..cc821be 100644 --- a/initdb.d/27-freq.sql +++ b/initdb.d/27-freq.sql @@ -4,4 +4,7 @@ CREATE TABLE "frequency" ( PRIMARY KEY ("entry") ); -CREATE INDEX "idx_frequency_frequency" ON "frequency"("frequency"); +CREATE INDEX "idx_frequency_frequency" ON "frequency" ("frequency"); +CREATE INDEX "idx_frequency_entry" ON "frequency" + USING pgroonga("entry") + WITH (normalizer='NormalizerNFKC100("unify_kana", true)');