How to use Postgresql GIN index with ARRAY keyword - arrays

I'd like to create GIN index on a scalar text column using an ARRAY[] expression like so:
CREATE TABLE mytab (
scalar_column TEXT
)
CREATE INDEX idx_gin ON mytab USING GIN(ARRAY[scalar_column]);
Postgres reports an error on ARRAY keyword.
I'll use this index later in a query like so:
SELECT * FROM mytab WHERE ARRAY[scalar_column] <# ARRAY['some', 'other', 'values'];
How do I create such an index?

You forgot to add an extra pair of parentheses that is necessary for syntactical reasons:
CREATE INDEX idx_gin ON mytab USING gin ((ARRAY[scalar_column]));
The index does not make a lot of sense. If you need to search for membership in a given array, use a regular B-tree index with = ANY.

Related

Valid partition columns for external tables

I am trying to create an external table with various partition columns.
It works to do the following, for instance:
create or replace external table mytable(
myday date as to_date(substr(metadata$filename, 35, 10), 'YYYY-MM-DD'))
partition by (myday)
location = #mys3stage
file_format = (type = parquet);
However, I would like to use regex_substr instead of character indexing, as I won't always have consistent character indices for all partitioning columns. I would like to do this:
create or replace external table mytable(
myday date as to_date(regexp_substr(metadata$filename, 'day=[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]'), 'day=YYYY-MM-DD'))
partition by (myday)
location = #mys3stage
file_format = (type = parquet);
This gives me an error Defining expression for partition column MYDAY is invalid. I can run the regexp_substr clause successfully in a select statement outside of the external table creation, getting the same results as the substr approach.
How can I use regex string matching in my external table partition column definition?
REGEX_SUBSTR is not a function that is on the list of currently supported partition key functions. Please use the following link to see the list of acceptable functions:
https://docs.snowflake.com/en/sql-reference/sql/create-external-table.html#partitioning-parameters
I am not completely sure I understand how your folder structure wouldn't be consistent. Perhaps if you provided an example, this community can offer a more concise response. However, if you are unable to come up with a parsing mechanism that works, perhaps you could leverage the CASE statement to handle each unique folder structure that you may come across in your environment.

Remove double quotes from fts keywords?

I need indexing JSON values with fulltext index.
In Oracle:
CREATE INDEX index_name ON tab_name (json_col_name)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('section group CTXSYS.JSON_SECTION_GROUP SYNC (ON COMMIT)');
In SQL Server:
CREATE FULLTEXT INDEX ON tab_name (json_col_name)
KEY INDEX primary_key_name
ON ft_cat_name
[other options...];
Both of indexes are created successfully. But when I do some query with those indexes, I take some troubles in SQL.
When I try to find the reason, I found that's caused by word-breaker.
Word-breaker keeps unnecessary characters (double quote, colon) of all FIELDS and VALUES in json text as INDEX KEYWORDS.
SELECT * FROM sys.dm_fts_index_keywords (DB_ID('db_name'), OBJECT_ID('tab_name'))
Is there anybody faced this problem? And how to resolve?
I want to know how to config word-breakers to remove unnecessary characters from keywords when populate indexes in SQL.
I've tried indexing these columns with neutral language (LCID = 0) and all unnecessary symbols in JSON string are removed from the keywords.
CREATE FULLTEXT INDEX ON tab_name (json_col_name language 0)
KEY INDEX primary_key_name
ON ft_cat_name
[other options...];

Values of JSON exist in columns' JSONB array

I have tricky query that attempts to find matches that compare a list of JSON arrays against a list of JSON values in a column
The "Things" table with "Keywords" column would contain something such as:
'["car", "house", "boat"]'::JSONB
The query would contain the values:
'["car", "house"]'::JSONB
I'd like to find all the rows that have BOTH "car" and "house" contained in the listing. Here's my (mostly) feeble attempt:
SELECT
*
FROM
"Things"
WHERE
"Keywords"::JSONB ?| ARRAY(
SELECT * FROM JSONB_ARRAY_ELEMENTS('["house","car"]'::JSONB)
)::TEXT[]
Also when it comes to indexing, I'm assuming adding a GIST index would be my best option.
I'd like to find all the rows that have BOTH "car" and "house"
So the right operator is ?& - Do all of these array strings exist as top-level keys?
You query is almost correct, change the operator and use jsonb_array_elements_text():
WITH "Things"("Keywords") AS (
VALUES
('["car", "house", "boat"]'::jsonb),
('["car", "boat"]'),
('["car", "house"]'),
('["house", "boat"]')
)
SELECT
*
FROM
"Things"
WHERE
"Keywords" ?& array(
SELECT jsonb_array_elements_text('["house","car"]')
)
Keywords
--------------------------
["car", "house", "boat"]
["car", "house"]
(2 rows)
The query would be simpler if the argument could be written down as a regular array of text:
SELECT
*
FROM
"Things"
WHERE
"Keywords" ?& array['house', 'car']
In both cases you can use a GIN index:
The default GIN operator class for jsonb supports queries with top-level key-exists operators ?, ?& and ?| operators (...)

How do you iterate through the IndexCollection of each table in Microsoft.SqlServer.Management.Smo

I am trying to get lists of indexes and constraints per table in my Microsoft.SqlServer.Management.Smo application and I am having a hard time get the list of indexes to begin with.
If I am not mistaken each table has an Indexes property which is of type IndexCollection and it looks like it has a collection of IndexCollections as its items or elements.
For example if I have a reference to a SQL Server table called tbl I can refer to the indexes collection as follows:
tbl.Indexes
How do you iterate through the Indexes collection and get the list of indexes?
Try something like this:
// iterate over the indexes for this table
foreach (Index ix in tbl.Indexes)
{
string indexName = ix.Name;
string indexType = ix.IndexType.ToString();
string indexFilter = ix.FilterDefinition;
}
The IndexCollection is a collection of objects of type Index, which then contain a number of properties to get information about your indexes,.

Can you index elements of an array in Postgres?

I'm wondering if I can do something like
CREATE INDEX firstelement ON mytable (myarray[1]);
this particular syntax creates a syntax error.
Try this one, with extra parentesis:
CREATE INDEX firstelement ON mytable ((myarray[1]));

Resources