Fulltext Postgres - postgresql

I created an index for full text search in postgresql.
CREATE INDEX pesquisa_idx
ON chamado
USING
gin(to_tsvector('portuguese', coalesce(titulo,'') || coalesce(descricao,'')));
When I run this query:
SELECT * FROM chamado WHERE to_tsvector('portuguese', titulo) ## 'ura'
It returned to me some rows.
But when my argument is in all uppercase, no rows are returned. For example:
SELECT * FROM chamado WHERE to_tsvector('portuguese', titulo) ## 'URA'
When the argument is 'ura' I get a few lines; when the argument is 'URA' I do not get any rows.
Why does this happen?

You get no matches in the second case since to_tsvector() lowercases all lexemes. Use to_tsquery() to build the query, it will take care of the case issues as well:
SELECT * FROM chamado WHERE to_tsvector('portuguese', titulo) ## to_tsquery('portuguese', 'URA')

Related

PostgreSQL execute SELECT * FROM (t as a); return ERROR: syntax error at or near ")"

Why these SQLs can't work in PostgreSQL?
SELECT * FROM (t as a);
or
SELECT * FROM (t);
ERROR: syntax error at or near ")"
Those SQLs work well in MySQL.
Well, it's invalid SQL.
If you want to give the table an alias you need to use from t as a.
The form from (....) requires a valid query inside the parentheses and t as a (or just t) is not a valid query. Additionally: a derived table (which is what (...) defines) requires an alias. So at least it has to be from (...) as bla
To get all rows and all columns from a table the SQL standard provides the shortcut table some_table which is supported by Postgres.
So the following would be valid:
select * from (table t) as a
Typically, table alias' are applied where there is a join. For example:
SELECT alias1.login_name, alias2.name
FROM tablename1 AS alias1
JOIN tablename2 AS alias2
ON alias1.id = alias2.role_id;
To apply an alias to a single table:
SELECT * FROM tablename AS alias;
..will do it for you, no need for parentheses.
You can confirm/test by example below if value is an integer:
SELECT * FROM tablename AS alias
WHERE alias.colum = value;
..or if value is a string:
SELECT * FROM tablename AS alias
WHERE alias.colum = 'value';
postgreSQL is strongly-typed, so the first example above will work for Int and Bool values, however if you have Date or other values, you may need to apply type casting. See this link for helpful info*: www.postgresqltutorial.com/postgresql-tutorial/postgresql-cast.
**Remember: For psql strings, always use single quotes for values, use double quotes for table names and column names.

Substring last 3 characters of an id of an object within an area

I am intending to grab the last three characters from an id. In my code, you can see that I am using ST_WITHIN() to get an object within another object. I am then grabbing the "node_id" of all objects within that area. Below is the code:
SELECT SUBSTRING ((
SELECT "node_id" from sewers.structures
WHERE(
ST_WITHIN(
ST_CENTROID((ST_SetSRID(structures.geom, 4326))),
ST_SetSRID((SELECT geom FROM sewers."Qrtr_Qrtr_Sections" WHERE "plat_page" = '510C'),4326)) )),5,3)
This portion of the code works without issue:
SELECT "node_id" from sewers.structures
WHERE(
ST_WITHIN(
ST_CENTROID((ST_SetSRID(structures.geom, 4326))),
ST_SetSRID((SELECT geom FROM sewers."Qrtr_Qrtr_Sections" WHERE "plat_page" = '510C'),4326)) )
But when I run the SELECT SUBSTRING() on the selection, I get the following error:
ERROR: more than one row returned by a subquery used as an expression
SQL state: 21000
The substring function should be called on each element, not on the entire query:
SELECT SUBSTRING("node_id",5,3)
FROM sewers.structures
WHERE ST_WITHIN ...

returning negative matches in Postgres

Let us say that I want to find rows that contain a match. For example:
select * from tableName where tableName.colName like '%abc%' limit 5;
This is going to give me rows that contain the substring abc within the column colName in the table tableName. Now, how do I get rows rows where the column colName does not contain the string abc. Is there some sort of a negation operator in Postgres?
Use not like:
select * from tableName where tableName.colName not like '%abc%' limit 5;

Is Null in OrientDB

In my database IM_0609 OrientDB version 2.0.8 is a class MARKS:
CALIBRATION_DATE:date.
DEVICE_MARK:string
DEVICE_NAME:string
END_MARK_NUM:decimal
MARK_NUM:decimal
PERIOD:decimal
SERIAL_NUM:string
In the class MARKS of 42898973 rows and I have created the index as follows:
CREATE INDEX MARK_NUM_END_MARK_NUM on MARKS(MARK_NUM,END_MARK_NUM) NOTUNIQUE
I run the following query quickly:
select * from MARKS where (MARK_NUM =84278511 AND END_MARK_NUM
=84278511 AND END_MARK_NUM IS NOT NULL)
1 item(s) found. Query executed in 0.097 sec(s).
And this requires a request to create an index or update query:
select * from MARKS where MARK_NUM =84278511 AND END_MARK_NUM IS NULL
The server displays the following message:
2015-05-12 15:46:43:129 INFO {db=IM_0609} [TIP] Query 'select * from MARKS where MARK
_NUM =84278511 AND END_MARK_NUM IS NULL' fetched more than 50000 records: to speed up
the execution, create an index or change the query to use an existent index [OProfiler
]
Q: Why do so runs the second query?
Orientdb does not keep index for null values if you don't specifically said to do that. To do that you have to set the metadata tag as follows:
CREATE INDEX addresses ON Employee (address) notunique METADATA {ignoreNullValues : false}
But your first query
select * from MARKS where (MARK_NUM =84278511 AND END_MARK_NUM =84278511 AND END_MARK_NUM IS NOT NULL)
says specific value for the END_MARK_NUM=84278511 and therefore it can use the index and limit the record reads < 50000
But your second query
select * from MARKS where MARK_NUM =84278511 AND END_MARK_NUM IS NULL
does not says a specific value for END_MARK_NUM and therefore it can't use your index. Therefore the number of record reads increases and it gives the tip saying "try to reduce the number of record reads that orientdb has to perform"
Edit: There seems to be a bug in the ignoreNullValues functionality. (https://github.com/orientechnologies/orientdb/issues/4508)
Seems like you simply have too many records matching the query. Also, did you mean to have 'IS NOT NULL' in the first query but 'IS NULL' in the second?
Try with a limit
select * from MARKS where MARK_NUM =84278511 AND END_MARK_NUM IS NULL LIMIT 10
This query runs instantly:
select * from index:MARKS.MARK_NUM_END_MARK_NUM where key=[84278511,NULL]
Q:But how do I get the fields of my class MARKS?

Best way to search in postgres by a group of keyword

right now I have a keyword array like:
['key1', 'key2', 'key3'.......] , the keyword can be number or character.
If I want to search in my table (postgres database), and find out all record contain any of keyword in that array, how can I do that?
For example:
I got a table which has a column called name and a column called description
I need find all record that either name or description contains any keywords in that array.
thanks
Maybe this example will be useful:
CREATE TABLE TEST(
FIELD_KEY TEXT);
INSERT INTO TEST VALUES('this is hello');
INSERT INTO TEST VALUES('hello');
INSERT INTO TEST VALUES('this');
INSERT INTO TEST VALUES('other message');
SELECT *
FROM TEST
WHERE FIELD_KEY LIKE ANY (array['%this%', '%hel%']);
This will return:
this is hello
hello
this
Here other example:
SELECT *
FROM TEST
WHERE FIELD_KEY ~* 'this|HEL';
~* is case insensitive, ~ is case sensitive
You can try this example here.
select *
from t
where
array[name] <# my_array
or array[description] <# my_array
Couple the like operator with the any subquery expression:
select *
from t
where name like any (values ('%John%'), ('%Mary%'))
Or the array syntax:
where name like any (array['%John%', '%Mary%'])