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.

  • You can see from the link that you have provided that only jsonb can be indexed with gin. And you are clearly trying to create an index on the column that is type of json. If you can't change column type you can have for examle btree index on some key in the json. Like so: CREATE INDEX ON api((column->>'id'));
    – ffox003
    May 24, 2017 at 10:17
  • @Munish Dhiman,The default GIN operator class for jsonb supports queries with the @>, ?, ?& and ?| operators. May 24, 2017 at 10:26
  • dba.stackexchange.com/questions/145586/… .. it is duplicate thread May 24, 2017 at 10:28
  • @ffox003 Yes you are right, I just mixed json and jsonb datatypes in my mind. Thanks :) May 24, 2017 at 11:02
  • @Munish Dhiman, what you executing the query? Could you mention. May 24, 2017 at 11:17

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

For further ref Here and 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.

  1. Converts the text to an JSON object.
  2. Stores that object using indexable Javascript primitives (binary).

That type in jsonb. So convert jdoc from JSON to JSONB,

  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));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.