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
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.
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...];
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 (...)
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,.
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]));