Using FTS3/4 Table based on Select Statements from Normal Table - android

In my app, I'm developing in Android, I have a Sqlite Table called Transactions, with these fields:
_Id | Date | Value | Notes
I already have a ListView showing results filtering by Date (for example):
Select * FROM Transacions WHERE Date BETWEEN '2016-04-25' AND '2016-05-14'
It works fine, but I want to implement a SearchView to search transactions between a custom date have in field Notes, some text typed in SearchView.
I read about adding a SearchView, and the best way to implement to search is using a FTS3 or FTS4 Table, allowing the user, for example, type "SUPERMARKET" and find a Transaction where the Notes have this text.
The problem appears because a FTS table is slow to perform WHERE conditions (like the above, to filter date)...
How can I implement both Filtering date, using WHERE date BETWEEN ... and ..., and filtering text Notes with the performance of a FTS Table?
If it is not possible to do so, is it a good idea to have a query like this:
Select * FROM Transacions WHERE (Date BETWEEN '2016-04-25' AND '2016-05-14) AND Notes LIKE '%text%''?

Do not think of an FTS table as a table, but as an index.
With the notes indexed like this:
CREATE VIRTUAL TABLE Transactions_FTS USING FTS4(Notes);
you would have to ensure that the IDs of both tables match, and could then combine the tables like this:
SELECT *
FROM Transactions
WHERE Date BETWEEN '2016-04-25' AND '2016-05-14'
AND _Id IN (SELECT docid
FROM Transactions_FTS
WHERE Notes MATCH 'supermarket');
or this:
SELECT *
FROM Transactions
JOIN Transactions_FTS ON Transactions._Id = Transactions_FTS.docid
WHERE Date BETWEEN '2016-04-25' AND '2016-05-14'
AND Transactions_FTS.Notes MATCH 'supermarket';
(If you care about the amount of storage used, consider an external content FTS table.)

Related

Sqlite order by rows order

I am using this query
"select * from SomeTable group by SomeColumn"
It is returns list with accenting order, but i need to same order like in database.
For example the order in database is:
p
a
s
But result is:
a
i
p
Sample
The result need to be like distinct by CityEN but with all columns and order like 1.Paris 2.Amsterdam 3.Istanbul
In Sqlite, each row of a table has a unique rowid, which you can use for sorting.
select * from SomeTable group by SomeColumn order by rowid;
In your statement, add this line to sort the results:
order by min(rowid)
Your query does not enforce any order with ORDER BY clause so no assumption about row order should be made. If you want specific order add i.e. ORDER BY SomeColumn. See docs about all available order options: https://www.sqlite.org/lang_select.html#orderby
By the rules of SQL, you can't count on getting records back in any specific order without specifying an ORDER BY clause in your SQL query.
In practice servers sometimes return values in the order in which they're inserted, in the order of the first index created, or in the order of the primary key--but you can't count on this behavior, and in fact I've seen the behavior change between database maintenance windows or after the database version is upgraded. You definitely wouldn't want to count on a DB engine to give you back records in any particular order if you write a SELECT statement without an ORDER BY clause.
The only real way to get your records back in the order you inserted them is to create a timestamp column and then sort on it during the SELECT. If you don't want to worry about populating that column on INSERT, have that column auto-populate itself with a timestamp (depending on your DB engine).

How to do a word search on a large text database

I have a large database in my app. One column is made of text strings that are about a sentence to a paragraph long. I would like to make this column searchable by word(s) that the user inputs.
How would I make a quick search? I've heard of making an index but I don't know how to do that for a text search.
SQLite has a mechanism for storing a lot of text in a database, it's called FTS (short for full text search).
Android supports all SQLite commands, so you can easily just use FTS3.
How is explained in the documentation linked above.
Example for creating a table:
CREATE VIRTUAL TABLE enrondata1 USING fts3(content TEXT); /* FTS3 table */
CREATE TABLE enrondata2(content TEXT); /* Ordinary table */
Query:
SELECT count(*) FROM enrondata1 WHERE content MATCH 'linux'; /* 0.03 seconds */
SELECT count(*) FROM enrondata2 WHERE content LIKE '%linux%'; /* 22.5 seconds */

SQLite Fts select query

I am making a dictionary of over 20,000 words in it. So, to make it work faster when search data, i am using fts3 table to do it.
my select query:
Cursor c=db.rawQuery("Select * from data where Word MATCH '"+word+"*'", null);
Using this query, it will show all the word that contain 'word' , but what i want is to get only the word that contain the beginning of the searching word.
Mean that i want it work like this query:
Cursor c=db.rawQuery("Select * from data where Word like '"+word+"%'", null);
Ex: I have : apple, app, and, book, bad, cat, car.
when I type 'a': i want it to show only: apple, app, and
What can i solve with this?
table(_id primary key not null autoincrement, word text)
FTS table does not use the above attributes. It ignores data type. It does not auto increment columns other than the hidden rowid column. "_id" will not act as a primary key here. Please verify that you are implementing an FTS table
https://www.sqlite.org/fts3.html
a datatype name may be optionally specified for each column. This is
pure syntactic sugar, the supplied typenames are not used by FTS or
the SQLite core for any purpose. The same applies to any constraints
specified along with an FTS column name - they are parsed but not used
or recorded by the system in any way.
As for your original question, match "abc*" already searches from the beginning of the word. For instance match "man*" will not match "woman".
FTS supports searching for the beginning of a string with ^:
SELECT * FROM FtsTable WHERE Word MATCH '^word*'
However, the full-text search index is designed to find words inside larger texts.
If your Word column contains only a single word, your query is more efficient if you use LIKE 'a%' and rely on a normal index.
To allow an index to be used with LIKE, the table column must have TEXT affinity, and the index must be declared as COLLATE NOCASE (because LIKE is not case sensitive):
CREATE TABLE data (
...
Word TEXT,
...
);
CREATE INDEX data_Word_index ON data(Word COLLATE NOCASE);
If you were to use GLOB instead, the index would have to be case sensitive (the default).
You can use EXPLAIN QUERY PLAN to check whether the query uses the index:
sqlite> EXPLAIN QUERY PLAN SELECT * FROM data WHERE Word LIKE 'a%';
0|0|0|SEARCH TABLE data USING INDEX data_Word_index (Word>? AND Word<?)

android _Displaying a record from a sqlite database

I am planning to build an app that lets the user select a record from a particular database such as:
name favorite_color favorite_team
sue red Dal
mike blue Mia
sam purple Bal
My problem is that most of the tutorials that I have come across only demonstrates examples using a table with one column. What if my pre-populated database more then on column? What if it had 100 columns? Does anyone know how this is done?????
Here's an example:
Step1:Declare SQLiteDatabase,Declare Databasehelper
Step2:Declare string or number which is to be used as key or get it as an intent(in this example 'rowid'
Step 3: In the OnCreate method add lines of code similar to following:
String query="select * from my_table_name where _id="+rowid;
Cursor myCursor = database.rawQuery(query,null);
myCursor.moveToFirst();
//This line implies i am getting data from column four of selected row
String x=myCursor.getString(4);
//This line implies i am getting data from column two of selected row
String y=myCursor.getString(4);
myCursor.close();
Note:
a)Don't forget that your database size must not exceed 1.2mb
b)Also include a column with name _id which auto-increments in each table that you are using,you may use sqlite browser to do so
c)also create the following table in your database :
CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US')
Now insert a single row with the text 'en_US' in the "android_metadata" table
INSERT INTO "android_metadata" VALUES ('en_US')
read this you will learn every thing you need to know. One other way to access db information is using an ORM like ormlite. I'm using it in various apps that i've developed, and it's simple to use.

Best way to search sqlite database

In my application ,am work with a large database.Nearly 75000 records present in a table(totally 6 tables are there).i want to get a data from three different table at a time.i completed that.but the search process was slow.how can i optimise the searching process?
You might want to consider using the full-text search engine and issuing SELECT...MATCH queries instead. Note that you need to enable the FTS engine (it's disabled by default) and create virtual tables instead of regular tables. You can read more about it here.
Without being able to see the table structure (or query) the first thing I'd suggest is adding some indexes to the tables.
Lets say you have a few tables like:
Author
id
last_name
first_name
Subject
id
name
Book
id
title
author_id
subject_id
and you're wanting to get all the information about each of the books that an author with last_name="Smith" and first_name="John" wrote. Your query might look something like this:
SELECT * FROM Book b
LEFT JOIN Subject s
ON s.id=b.subject_id
LEFT JOIN Author a
ON a.id=b.author_id
WHERE a.last_name='Smith'
AND a.first_name='John';
There you'd want the last_name column in the Author table to have an index (and maybe first_name too).

Categories

Resources