I need to add index on a JSON column in my table as per documentation I am executing a query similar to the one below.
CREATE INDEX idxgin ON api USING gin (jdoc);
I am getting following error:
ERROR: data type json has no default operator class for access method "gin"
HINT: You must specify an operator class for the index or define a default operator class for the data type.
Here is the link for the documentation.
3 Answers 3
GiN(Generalized Inverted Index) is inverted index, a structure that has only a single index entry per a key and stores the mapping information(posting list) of all key rows to have the same value in the index entry. In postgreSQL, the key is stored in the index entry and mapping information for the key is stored in the posting tree. To search the index entry and posting tree a B-Tree is used. Therefore, GIN is useful when an index must map many values on a row, such as indexing array, documents.
I suppose to that before creating a GIN index, you are making some mistake. as you see here PostgreSQL GIN pg_trgm default operator class
To Creates a GIN (Generalized Inverted Index) the syntax should be like
CREATE INDEX name ON table USING gin(column);
Creates a GIN (Generalized Inverted Index)-based index. The column must be of tsvector type.
Default operator class jsonb_ops supports existence operators( ?, ?&, ?| ) and containment operator( @> ). And jsonb_path_ops supports the containment operator only. Therefore GIN index is only possible to search for a particular key or key-values.
When we use ->> operator of JSONB, PostgreSQL can use B-tree or Hash index for processing the operations. ->> operator returns the value of the specified attribute in text format. PostgreSQL can use indexes for the text results as compare operands. GIN index can be used by GIN jsonb operator class.
To see the json operator Here
JSON is a json-validated text type: a Javascript object serialized into text. You can't usefully index that. You can only index data. In order to make that text data, we move it into a format that we makes sense.
- Converts the text to an JSON object.
- Stores that object using indexable Javascript primitives (binary).
That type in jsonb. So convert jdoc
from JSON to JSONB,
ALTER TABLE api
ALTER COLUMN jdoc
SET DATA TYPE jsonb USING jdoc::jsonb;
Now your exact query above will work.
Seems this also works: CREATE INDEX idxgin ON api USING gin ((jdoc::jsonb));
jsonb
can be indexed withgin
. And you are clearly trying to create an index on the column that is type ofjson
. If you can't change column type you can have for examlebtree
index on some key in thejson
. Like so:CREATE INDEX ON api((column->>'id'));