MariaDB MATCH AGAINST with single quote search term? - sql

I'm trying to find a working query for using MATCH AGAINST while having a search term containing a single quote.
Example data in the database table:
I'm a freak
Example search term:
I'm
Search queries I tried:
SELECT * FROM table WHERE MATCH (name) AGAINST ('"I\'m"' IN NATURAL LANGUAGE MODE);
SELECT * FROM table WHERE MATCH (name) AGAINST ('"I\'m"' IN BOOLEAN MODE);
SELECT * FROM table WHERE MATCH (name) AGAINST ('I\'m*' IN BOOLEAN MODE);
SELECT * FROM table WHERE MATCH (name) AGAINST ('(I\'m)*' IN BOOLEAN MODE);
...and many more. Nothing is working.
I'm using MariaDB 10.1.33.
Any ideas?

I'm pretty sure contractions are not treated as words.
Instead the apostrophe is treated as a word separator giving you "I" and "m".
But you probably don't have innodb_ft_min_token_size=1, so those two "words" are ignored.
There are limitations of FT; you have encountered one of them.

Related

How to restrict entire FTS5 Query to a single column?

Currently, I'm trying to execute an FTS5 query via libsqlite, and need to restrict the query to a specific column. In FTS4, this was possible by doing:
SELECT foo, bar FROM tableName WHERE columnName MATCH ?
and then binding the search string to the statement. However, with FTS5, the LHS of the MATCH operator must be the FTS table name itself, and the column name must be a part of the query:
SELECT foo, bar FROM tableName WHERE tableName MATCH 'columnName:' || ?.
This works when the binded string is a single phrase. However, consider the search text this is great. The query then becomes:
SELECT foo, bar FROM tableName WHERE tableName MATCH 'columnName:pizza is great';
Only pizza is restricted to to the columnName, but the rest of the phrase is matched against all columns.
How can I work around this?
The documentation says:
A single phrase … may be restricted to matching text within a specified column of the FTS table by prefixing it with the column name followed by a colon character.
So the column name applies only to a single phrase.
If you have three phrases, you need to specify the column name three times:
tableName MATCH 'columnName:pizza columnName:is columnName:great'

sqlite3 with FTS4 table: Query returns wrong row

I have a weird issue with my FTS4 index in SQLite3, namely that a MATCH query for one term returns not the exact match but another, similar one, and vice versa.
Here is an example to illustrate it better:
SELECT name FROM test_idx WHERE name MATCH 'lehmbruck-museum';
-- "Lehmbruck-Archiv"
SELECT name FROM test_idx WHERE name MATCH 'lehmbruck-archiv';
-- "Lehmbruck-Museum"
It seems to have something to do with the dash, here is a similar case that exhibits the same behavior:
SELECT name FROM test_idx WHERE name MATCH 'some-thing';
-- "some-thang"
SELECT name FROM test_idx WHERE name MATCH 'some-thang';
-- "some-thing"
Here is how this test database is built, in case somebody wants to have a go at reproducing it:
CREATE VIRTUAL TABLE test_idx USING fts4(name);
INSERT INTO test_idx (name) VALUES
('some-thing'), ('some-thang'),
('Lehmbruck-Museum'), ('Lehmbruck-Archiv');
SELECT name FROM test_idx WHERE name MATCH 'lehmbruck-museum';
What you pass to MATCH here is a full text query expression. The - character is a unary operator in that expression language that is a stand in for the NOT set operation, and is certainly giving you your unexpected results. Notably - the exact opposite of what you expect! Of course, it is finding exactly what the query is instructed to find - the string lehmbruck and NOT museum at the end!
You'll need to escape it to get the results you want - or perhaps employ the LIKE operator if you are looking at a single column in a table.
Some more information on this expression language can be found in section 3 of the FTS3 and FTS4 documentation on the SQLite doc site here.

SQLite FTS4: A query containing a single unary not expression?

The SQLite3 FTS4 documentation regarding the standard query unary - operator states:
An FTS query may not consist entirely of terms or term-prefix queries
with unary "-" operators attached to them.
Is there any way around this? Specifically, I want to retrieve all the rows in my table that do not contain a term or term-prefix.
sqlite> select * from search;
1|Clock
2|Un
sqlite> select id from search where text match 'Un';
2
sqlite> select id from search where text match 'clock -Un';
1
sqlite> select id from search where text match '-Un';
Error: malformed MATCH expression: [-Un]
sqlite> select id from search where text match '-Un*';
Error: malformed MATCH expression: [-Un*]
select id
from search
where docid not in (select docid
from search
where text match 'Un')

SQL Server 2012 query string containing slash

I've looked all over the internet and stackoverflow for an answer to this question, but can't seem to find anything that answers it so here goes...
Is there anything special that needs to be done to a forward slash (/) for them to be included in search queries?
Scenario: I have a query that contains a string being searched for that includes a forward slash. The search term is a dimension of a particular item so it must contain the slash to indicate a fraction. I've tried escaping it with a backslash, but that doesn't work. The query is as follows:
SELECT * FROM ITEMDATA WHERE CONTAINS(dimensions, '3/8')
This query returns 0 results.
Example of data to be searched on:
•Pitch: 3/8"
•Gauge: .050
I also need to get the double quote in the search phrase to specify units, but that's another problem.
Any suggestions?
As the following demonstrates, you can use "/" in a LIKE expression without any tricks:
create table foo(a int, b varchar(32))
go
insert into foo select 1, 'for 3/8 inch';
go
select * from foo where b like '%3/8%';
go
This will result in the single row being found.
If we need to search in sql table column with a particular string, we need to use LIKE command, so that we can use it like in various ways.
1. Returns results having dimensions column value contains the string 3/8
'SELECT * FROM ITEMDATA WHERE dimensions LIKE '%3/8%';`
Returns results having dimensions column value strictly starts with the string 3/8
SELECT * FROM ITEMDATA WHERE dimensions LIKE '3/8%';
Returns results having dimensions column value strictly ends with the string 3/8.
SELECT * FROM ITEMDATA WHERE dimensions LIKE '3/8%';
Disable STOPLIST for full-text:
ALTER FULLTEXT INDEX ON table SET STOPLIST OFF
and try
SELECT * FROM ITEMDATA WHERE CONTAINS (dimensions, '"3/8*"')

Finding the "&" character in SQL SERVER using a like statement and Wildcards

I need to find the '&' in a string.
SELECT * FROM TABLE WHERE FIELD LIKE ..&...
Things we have tried :
SELECT * FROM TABLE WHERE FIELD LIKE '&&&'
SELECT * FROM TABLE WHERE FIELD LIKE '&\&&'
SELECT * FROM TABLE WHERE FIELD LIKE '&|&&' escape '|'
SELECT * FROM TABLE WHERE FIELD LIKE '&[&]&'
None of these give any results in SQLServer.
Well some give all rows, some give none.
Similar questions that didn't work or were not specific enough.
Find the % character in a LIKE query
How to detect if a string contains special characters?
some old reference Server 2000
http://web.archive.org/web/20150519072547/http://sqlserver2000.databases.aspfaq.com:80/how-do-i-search-for-special-characters-e-g-in-sql-server.html
& isn't a wildcard in SQL, therefore no escaping is needed.
Use % around the value your looking for.
SELECT * FROM TABLE WHERE FIELD LIKE '%&%'
Your statement contains no wildcards, thus is equivalent to WHERE FIELD = '&'.
& isn't a special character in SQL so it doesn't need to be escaped. Just write
WHERE FIELD LIKE '%&%'
to search for entries that contain & somewhere in the field
Be aware though, that this will result in a full table scan as the server can't use any indexes. Had you typed WHERE FIELD LIKE '&%' the server could do a range seek to find all entries starting with &.
If you have a lot of data and can't add any more constraints, you should consider using SQL Server's full-text search to create and use and FTS index, with predicates like CONTAINS or FREETEXT