如何使用Knex.js添加GIN索引
问题描述:
我一直试图添加一个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数据库。任何人都可以告诉我,如果这是实现这个的正确方法?如果是,我的代码有什么问题,如果不是如何实现呢?谢谢!
答
您应该能够创建完整的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=#
答
那些正在寻找更多的“双膝”解决方案来解决这个问题:没有必要像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
就足够了。
感谢您的回复。我使用的是与你所建议的相同的查询,但由于某种原因,我无法在同一个迁移中创建索引,我试图创建一个表(注:我试图在创建表后创建一个索引)。所以我创建了两个单独的迁移(创建表,创建索引),这很好运作 –
@HarshalGangurde,这真的很奇怪......我确实通过https://runkit.com/embed/8fm3z9xzjz9b呈现了查询,并且在psql里面运行了它们一个交易,像knex运行它们,一切正常。我会更新答案。 –