2017-08-24 92 views
0

我一直試圖添加一個GIN索引使用Knex.js在我的表中的一列,但我無法實現這一點。我試圖做這樣的事情 -如何使用Knex.js添加GIN索引

exports.up = function(knex, Promise) { 
    return knex.schema.createTable('prediction_models', function(table){ 
      table.increments('id'); 
      table.string('model_name').index(); 
      table.jsonb('model_params'); 
      table.timestamp('createdAt').defaultTo(knex.fn.now()); 
     }) 
     .then(createGinIndex()); 

    function createGinIndex() { 
     return knex.raw('CREATE INDEX modelgin ON public.prediction_models USING GIN (model_params);'); 
    } 
}; 

exports.down = function(knex, Promise) { 
    return knex.schema.dropTable('prediction_models'); 
}; 

我正在使用PostgreSQL數據庫。任何人都可以告訴我,如果這是實現這個的正確方法?如果是,我的代碼有什麼問題,如果不是如何實現呢?謝謝!

回答

0

您應該能夠創建完整的GIN指數是這樣的:

CREATE INDEX on prediction_models USING GIN (model_params) 

有關創建jsonb列的索引的更多信息可以從https://www.vincit.fi/en/blog/objection-js-postgresql-power-json-queries/

最後找到可以打印查詢運行通過遷移這樣的(http://runkit.com/embed/8fm3z9xzjz9b):

var knex = require("knex")({ client: 'pg' }); 
const queries = knex.schema.createTable('prediction_models', function (table){ 
    table.increments('id'); 
    table.string('model_name').index(); 
    table.jsonb('model_params'); 
    table.timestamp('createdAt').defaultTo(knex.fn.now()); 
}).raw('CREATE INDEX on prediction_models USING GIN (model_params)') 
.toSQL(); 

queries.forEach(toSql => console.log(toSql.sql)); 

,並將它們複製並粘貼到psql的:

mikaelle=# begin; 
BEGIN 
mikaelle=# create table "prediction_models" ("id" serial primary key, "model_name" varchar(255), "model_params" jsonb, "createdAt" timestamptz default CURRENT_TIMESTAMP); 
CREATE TABLE 
mikaelle=# create index "prediction_models_model_name_index" on "prediction_models" ("model_name"); 
CREATE INDEX 
mikaelle=# CREATE INDEX on prediction_models USING GIN (model_params); 
CREATE INDEX 
mikaelle=# commit; 
COMMIT 
mikaelle=# 
mikaelle=# \d prediction_models 
            Table "public.prediction_models" 
    Column |   Type   |       Modifiers        
--------------+--------------------------+---------------------------------------------------------------- 
id   | integer     | not null default nextval('prediction_models_id_seq'::regclass) 
model_name | character varying(255) | 
model_params | jsonb     | 
createdAt | timestamp with time zone | default now() 
Indexes: 
    "prediction_models_pkey" PRIMARY KEY, btree (id) 
    "prediction_models_model_name_index" btree (model_name) 
    "prediction_models_model_params_idx" gin (model_params) 

mikaelle=# 
+0

感謝您的回覆。我使用的是與你所建議的相同的查詢,但由於某種原因,我無法在同一個遷移中創建索引,我試圖創建一個表(注:我試圖在創建表後創建一個索引)。所以我創建了兩個單獨的遷移(創建表,創建索引),這很好運作 –

+0

@HarshalGangurde,這真的很奇怪......我確實通過https://runkit.com/embed/8fm3z9xzjz9b呈現了查詢,並且在psql裏面運行了它們一個交易,像knex運行它們,一切正常。我會更新答案。 –

0

那些正在尋找更多的「雙膝」解決方案來解決這個問題:沒有必要像MikaelLepistö的解決方案那樣使用.raw。可鏈接的.index接受稱爲indexType的第二個參數。它可用於像這樣:

knex.schema.createTable('table_name', table => { 
    table.jsonb('column_name').index(null, 'GIN') 
}) 

(第一個參數的null被我說:「名字這一指數爲我」)

這段代碼將產生如下疑問:

create table "table_name" ("column_name" jsonb); 
create index "table_name_column_name_index" on "table_name" using GIN ("column_name") 

目前我創建了這樣一個索引,但出於性能原因,我希望它只支持jsonb_path_ops操作符類(按照section 8.14.4 of the documentation)。這需要以using GIN ("column_name" jsonb_path_ops)結尾的create index聲明。因此,我需要使用原始碼,但有大量的使用案例.index就足夠了。