My virtual table is:
CREATE VIRTUAL TABLE docs USING fts4();
INSERT INTO docs(docid, content) VALUES(1, 'sqlite is a database');
INSERT INTO docs(docid, content) VALUES(2, 'my database is sqlite');
When I use this query:
SELECT * FROM docs WHERE docs MATCH 'sqlite AND database';
it returns both 2 records in the table because both of them contain the term "sqlite" and the term "database".
Now, I want to search for records that contain the term "sqlite" and the term "database" with this rule:
The order in which the terms appear in the document has to be the same as the order in which they appear in the query (document with docid 1 only).
Is it possible?
FTS queries cannot restrict the order of terms, except for phrase searches, which require consecutive terms (e.g., "sqlite database" would not match sqlite is a database).
You have to restrict the results afterwards:
SELECT ... WHERE docs MATCH 'sqlite AND database'
AND content LIKE '%sqlite%database%';
Related
Using a FTS5 virtual table returns nothing for postfix searches.
It only can search for the entire word tokens, or for the prefixes of the word tokens if I append * to the search.
For example, it does not find qwerty.png row, if I search for werty.
CREATE TABLE IF NOT EXISTS files (name TEXT, id INTEGER);
INSERT INTO files (name, id) VALUES ('qwerty.png', 1), ('asdfgh.png', 2);
CREATE VIRTUAL TABLE IF NOT EXISTS names USING FTS5(name);
INSERT INTO names (name) SELECT name FROM files;
SELECT *
FROM names
WHERE name MATCH 'werty';
It only works for prefix searches (qwerty, qwer*, qwe*, ...).
I can't use * at the start of the search (*werty), since it produces an error.
Is possibly to make the indexed text search working as if I would use
SELECT *
FROM names
WHERE name like '%wert%';
?
I just want to have the fast search for a substring without the full table scan.
Perhaps try the experimental trigram tokenizer
When using the trigram tokenizer, a query or phrase token may match any sequence of characters within a row, not just a complete token.
I am using DB Browser for SQLite. The documentation for SQLite's fts3 says "FTS is primarily designed to support Boolean full-text queries". I built a virtual table using fts4 and successfully executed a few WHERE ... MATCH queries. But the following attempts give errors:
SELECT id FROM histsearch WHERE id MATCH ("-1456" IN BOOLEAN MODE);
SELECT id FROM histsearch WHERE NOT EXIST id MATCH ("1457");
Is the problem in DB Browser or in SQLite? How else can I write this query so it will work?
SQLite's full text service (fts3) basically offers Boolean Mode by default, no search modifier needed. DB Browser uses fts's standard query syntax, so NOT is not supported. To exclude a term, do something like
SELECT * FROM indexed WHERE indexed MATCH 'sqlite -database';
Edit: however, you cannot only exclude search terms in fulltext search:
An FTS query may not consist entirely of terms or term-prefix queries with unary "-" operators attached to them.
You'll have to use NOT LIKE for that.
Problem description
I want to search for the query = Angela in a database from a table called Variations. The problem is that the database does not Angela. It contains Angel. As you can see the a is missing.
Searching procedure
The table that I want to query is the following:
"CREATE TABLE IF NOT EXISTS VARIATIONS
(ID INTEGER PRIMARY KEY NOT NULL,
ID_ENTITE INTEGER,
NAME TEXT,
TYPE TEXT,
LANGUAGE TEXT);"
To search for the query I am using fts4 because it is faster than LIKE% especially if I have a big database with more than 10 millions rows. I cannot also use the equality since i am looking for substrings.
I create a virtual table create virtual table variation_virtual using fts4(ID, ID_ENTITE, NAME, TYPE, LANGUAGE);
Filled the virtual table with VARIATIONS insert into variation_virtual select * from VARIATIONS;
The selection query is represented as follow:
SELECT ID_ENTITE, NAME FROM variation_virtual WHERE NAME MATCH "Angela";
Question
What am I missing in the query. What I am doing is the opposite of when we want to check if a query is a subtring of a string in a table.
You can't use fts4 for this. From the documentation:
SELECT count(*) FROM enrondata1 WHERE content MATCH 'linux'; /* 0.03 seconds */
SELECT count(*) FROM enrondata2 WHERE content LIKE '%linux%'; /* 22.5 seconds */
Of course, the two queries above are not
entirely equivalent. For example the LIKE query matches rows that
contain terms such as "linuxophobe" or "EnterpriseLinux" (as it
happens, the Enron E-Mail Dataset does not actually contain any such
terms), whereas the MATCH query on the FTS3 table selects only those
rows that contain "linux" as a discrete token. Both searches are
case-insensitive.
So your query will only match strings that have 'Angela' as a word (at least that is how I interpret 'discrete token').
My SQL query is giving error while trying to execute query:
Error:
Query input must contain at least one table or query
INSERT into Posts (PostText,TimePosted, TID)
VALUES ('My Post','2013-04-11 13:50:18',
(SELECT MAX(TID) FROM Threads AS TID))
Combine the literal fields with the select & move the alias;
INSERT into Posts (PostText,TimePosted, TID)
SELECT 'My Post','2013-04-11 13:50:18', MAX(TID) AS TID FROM Threads
You have not specified table name in your query.
There are 3 fields in your table and you are sending 3 values (Last value by select query).
But you have not written table name for main query in which data to insert.
I have following tables:
-- table to keep articles titles
CREATE TABLE articles(id, title);
insert into articles (id,title) values (1,'sqlite example');
insert into articles (id,title) values (2,'sqlite query ');
insert into articles (id,title) values (3,'erlang example ');
insert into articles (id,title) values (3,'erlang otp ');
-- table to keep keywords that we would like to search.
create table keywords(id,keyword);
insert into keywords (id,keyword) values (1,'sqlite');
insert into keywords (id,keyword) values (2,'otp');
-- full text search table - copy of articles.
create virtual table articles_fts using fts4 (id,name);
-- populate table with articles titles.
insert into articles_fts(id,name) select id,title from articles;
Now I would like to find ALL articles that contains any of specified keywords.
Query like:
select * from articles_fts
where name match (select keyword from keywords);
returns only titles with sqlite in it (first keyword), so the other entries of keywords table are ignored.
Question:
How could I find all articles that contains any of specified keywords?
Thanks.
Use
select *
from articles_fts
WHERE articles_fts MATCH ( select group_concat(keyword, ' OR ')
from keywords
group by 'x' )
The group_concat function aggregates all keywords with a comma. If you replace commas with OR, it should produce a good FTS query.
Also see section 3 of the full text search feature reference regarding the OR keyword and the reference for aggregate functions.