Как я могу ссылаться на таблицу FTS4 с возможностью поиска в моем DAO без получения ошибки компилятора? - PullRequest
1 голос
/ 12 октября 2019

Android [документация FTS4] [1] для состояний Android «Этот класс будет иметь сопоставляемую таблицу SQLite FTS4 в базе данных». Должен ли я интерпретировать это как таблицу сопоставления SQLite FTS4, которая будет сгенерирована простым добавлением аннотации, или это означает, что мне нужно предоставить какую-то таблицу сопоставления, чтобы «связать» класс сущности FTS4 с виртуальной таблицей FTS4?

В настоящее время я предполагаю первое. Если это правильно, то как я могу использовать эту таблицу сопоставления на практике? Я считаю правильным сказать, что когда вы создаете сущность с аннотацией FTS4, она генерирует обычную таблицу и таблицу отображения, ни одна из которых на самом деле не является виртуальной таблицей FTS4, к которой можно обращаться с помощью функции MATCH. Так, что же отображает таблица сопоставления ?! Какая-то гипотетическая виртуальная таблица внешнего контента FTS4, которая реализована во время выполнения, возможно, во время обратного вызова или миграции базы данных? В таком случае, как я должен ссылаться на таблицу FTS4 с возможностью поиска в моем DAO без получения ошибки компилятора?

РЕШЕНО:

Оказывается, прежняя интерпретация была правильной и что отображениеСгенерированная таблица включает в себя виртуальную таблицу, необходимую для полнотекстового поиска. Я все еще думаю, что документация могла бы быть более ясной по этому вопросу, но в итоге реальная проблема заключалась в том, что моя зависимость от комнаты не была актуальной. D'ой!

1 Ответ

1 голос
/ 12 октября 2019

С помощью FTS 3 или 4 вы определяете базовую таблицу, а затем таблицу VIRTUAL с ключевым словом USING и соответствующими параметрами (такие как модуль FTS3 или FTS4 и параметры, которые ожидает модуль). Затем модуль FTS генерирует таблицы.

Например, в базе данных есть стандартная библейская таблица со столбцами книги TEXT, глава INTEGER, стих INTEGER и содержимое TEXT. Для FTS вы создаете виртуальную таблицу, используя что-то вроде

CREATE VIRTUAL TABLE bible_fts USING fts3(book,chapter INTEGER, verse INTEGER, content TEXT)
  • . Это единственная специальная таблица как таковая, следующие таблицы являются обычными таблицами, за исключением того, что модуль FTS создает их.

Когда выполняется оператор CREATE, создаются таблица bible_fts_content, bible_fts_segments и bible_fts_segdir. (может быть немного по-другому для FTS4). Готовая к использованию FTS версия SQLite сможет обрабатывать такие вещи, как MATCH.

Короче говоря, все зависит от специальной обработки определенного модуля.

Если вы не можете сказать, очень непонятномне мои обязанности здесь!

Насколько я понимаю, вы должны определить основные таблицы.

Вы кодируете соответствующую аннотацию @FTS (3 или 4) Room генерирует виртуальную таблицу, например, вы получаете что-то вроде: -

    _db.execSQL("CREATE TABLE IF NOT EXISTS `device_item` (`id` INTEGER, `initial` TEXT, `added1` INTEGER NOT NULL DEFAULT 0, `added2` TEXT DEFAULT '', PRIMARY KEY(`id`))");
    _db.execSQL("CREATE VIRTUAL TABLE IF NOT EXISTS `table1` USING FTS3(`name` TEXT, `mapToTable2` INTEGER NOT NULL, `mapToTable3` INTEGER NOT NULL)");
    _db.execSQL("CREATE TABLE IF NOT EXISTS `table2` (`id` INTEGER, `nameOfT2` TEXT, `anotherNameOfT2` TEXT, PRIMARY KEY(`id`))");
    _db.execSQL("CREATE TABLE IF NOT EXISTS `table3` (`id` INTEGER, `nameOfT3` TEXT, `anotherNameOfT3` TEXT, PRIMARY KEY(`id`))");
    _db.execSQL("CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)");
    _db.execSQL("INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '91a23aea1ab6e684828fad82668cb9a5')");
  • PS с созданным Roomкод фактически является библией комнаты.
  • Выше не сработает, потому что я просто поставил @ FTS3 и любую старую таблицу (есть ограничения). Я просто сделал это для демонстрации.

Тогда я считаю, что из-за аннотаций Дао и т. Д. Они ссылаются на то, что им нужно. Однако я подозреваю, что вам придется часто кодировать @Ignore. (На самом деле я никогда не использовал FTS, мой опыт был с инструментом, который я играл с инструментом преобразования некоммерческих баз данных в комнату и получил преобразование, работающее с FTS, то есть до стадии, когда Room принял схему базы данных мудро).

Вы также можете найти Включение SQLite FTS в комнате 2.1 использования.

Пример

Таблица ядра

Сущность Bible.java

@Entity(tableName = "bible")
public class Bible {

    @PrimaryKey
    Long id;
    String book;
    Long chapter;
    Long verse;
    String content;

    public Bible(){}

    @Ignore
    public Bible(String bookName, Long chapter, Long verse, String content) {
        this.book = bookName;
        this.chapter = chapter;
        this.verse = verse;
        this.content = content;
    }
    // ...... getters and setters nothing special
}

Сущность FTS

Поскольку книга и содержание являются текстовыми столбцами, они будут определены для FTS

BibleFTS.java

@Fts4(contentEntity = Bible.class) //<<<<<<<<<< the table to FTSalise
@Entity(tableName = "bible_fts")
public class BibleFTS {

    @PrimaryKey
    Long rowid; //<<<<<<<<<< MUST HAVE 
    String book;
    String content;
}
  • Неуверен в необходимости использования геттеров и сеттеров, первая попытка работала без
  • Неуверен в автогенерации аффекта (но Long не нуждается в @NonNull и не генерируется автоматически)

Дао

BibleDao.java (охватывает Библию и BibleFTS)

@Dao
public interface BibleDao {

    @Insert
    Long insertBibleRow(Bible bible);

    @Insert
    Long[] insertBibleRows(Bible... bibles);

    @Query("SELECT * FROM bible")
    List<Bible> getAllBibleRows();

    //<<<<<<<<<< USED TO REBUILD (Room might do this anyway think I saw it somewhere) >>>>>>>>>>
    @Query("INSERT INTO bible_fts(bible_fts) VALUES('rebuild')")
    void rebuild();

    //<<<<<<<<<< SEARCH The searchable columns >>>>>>>>>
    @Query("SELECT bible.book,bible.chapter,bible.verse,bible.content FROM bible_fts JOIN bible ON id = docid WHERE bible_fts MATCH :searchFor")
    List<Bible> searchFor(String searchFor);

}

База данных

Database.java

@androidx.room.Database(
        version = 1,
        entities = {
                Bible.class, //<<<<<<<<<<
                BibleFTS.class //<<<<<<<<<<
        })
abstract class Database extends RoomDatabase {


    abstract BibleDao bibleDao(); //<<<<<<<<<<
}

Тестовое задание

MainActivity.java (метод onCreate)

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mDatabase =  Room.databaseBuilder(this,Database.class,"devicitems")
            .allowMainThreadQueries()
            .build();
    mBibleDao = mDatabase.bibleDao();
    Bible b = new Bible("Geneisis",1L,1L,"In the begining some bright spark made a thinngy called Earth and said I shall rule over that little speck.");
    mBibleDao.insertBibleRow(b);
    mBibleDao.rebuild();
    List<Bible> found = mBibleDao.searchFor("in");
    for (Bible currentBible: found) {
        Log.d(
                "FOUNDIN",
                "Found in in :- Book" + currentBible.getBook() +
                        " - Chapter " + currentBible.getChapter() +
                        " - Verse " + currentBible.getVerse() +
                        "\n\t" + currentBible.getContent()
        );
    }
}

Результат

2019-10-12 21:37:00.584 30255-30255/? D/FOUNDIN: Found in in :- BookGeneisis - Chapter 1 - Verse 1
        In the begining some bright spark made a thinngy called Earth and said I shall rule over that little speck.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...