Estoy usando PostgreSQL. ¿Hay alguna forma de crear un índice solo en las claves del diccionario, no en los valores ?
Por ejemplo, imagine una columna jsonb como:
select data from tablename where id = 0; answer: {1:'v1', 2:'v2'} Quiero indexar en el conjunto de claves (o lista de claves) que es [1, 2] . Para acelerar consultas como:
select count(*) from tablename where data ? '2';Como puede ver en los documentos , hay una forma de indexar la columna por completo (claves + valores):
CREATE INDEX idxgin ON api USING GIN (jdoc);Esto no es bueno para mí, considerando que almaceno una gran cantidad de datos en valores.
Intenté esto antes:
CREATE INDEX test ON tablename (jsonb_object_keys(data));el error fue:
ERROR: set-returning functions are not allowed in index expressionsAdemás, no quiero almacenar claves en el diccionario como valor.
¿Me puedes ayudar?
Su ejemplo no tiene mucho sentido, ya que su cláusula WHERE no especifica una operación JSON, y su salida de ejemplo no es una sintaxis JSON válida.
Puede ocultar la función de devolución de conjuntos (y el agregado) en una función INMUTABLE:
create function object_keys(jsonb) returns text[] language SQL immutable as $$ select array_agg(jsonb_object_keys) from jsonb_object_keys($1) $$; create index on tablename using gin ( object_keys(data));Si lo hizo de esta manera, podría consultarlo formulado así:
select * from tablename where object_keys(data) @> ARRAY['2'];En su lugar, podría hacer que la función devuelva un JSONB que contenga una matriz en lugar de devolver una matriz de texto de PostgreSQL, si prefiere consultarlo de esa manera:
select * from tablename where object_keys_jsonb(data) @> '"2"'; No puedes usar un ? formulación, porque en JSONB eso es específicamente para objetos, no matrices. Si realmente quisieras usar ? , en su lugar, podría escribir una función que mantenga el objeto como un objeto, pero convierta todos los valores a JSON nulo o a una cadena vacía, para que ocupen menos espacio.