sqlite Android房间-未知的令牌化器- FtsOptions.TOKENIZER_UNICODE61

798qvoo8  于 2023-10-23  发布在  SQLite
关注(0)|答案(1)|浏览(105)

我正在使用FTS4和一个标记器来删除变音符号。数据库是用Room抽象的。
例如:

    • 内容**
@Entity(
        tableName = "test"
)
public class Test {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    private Long mId;

    @ColumnInfo(name = "name")
    String mName;

    public Test(String name) {
        mName = name;
    }

    public Long getId() {
        return mId;
    }

    public void setId(Long id) {
        mId = id;
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }
}
    • FTS**
@Entity(tableName = "search_fts")
@Fts4(
        contentEntity = Test.class,
        tokenizer = FtsOptions.TOKENIZER_UNICODE61,
        tokenizerArgs = {
                "remove_diacritics=2"
        }
)
public class SearchFts {

    @PrimaryKey
    @ColumnInfo(name = "rowid")
    int mRowId;

    @ColumnInfo(name = "name")
    String mName;

    public SearchFts(int rowId, String name) {
        mRowId = rowId;
        mName = name;
    }

    public int getRowId() {
        return mRowId;
    }

    public void setRowId(int rowId) {
        mRowId = rowId;
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }
}

这将导致一个SQLite查询:

CREATE VIRTUAL TABLE IF NOT EXISTS search_fts
USING FTS4(
     'name' TEXT,
     tokenize=unicode61 'remove_diacritics=2', content='test'
);

一切都适用于较新的Android版本(即。API 30),但在较旧的版本(即API 25或27)上,我得到以下错误:

android.database.sqlite.SQLiteException: unknown tokenizer (code 1)

官方文档:
"unicode61"标记器从SQLite版本3.7.13(2012 - 06 - 11)开始可用。Unicode61的工作方式非常像"simple",除了它根据Unicode 6.1版的规则进行简单的Unicode大小写折叠,它识别Unicode空格和标点字符,并使用它们来分隔标记。
API和数据库版本:

Logcat:
2022 - 07 - 26 11:36:56.532 16176 - 16229/hr. laserline. osis E/SQLiteLog:(1)语句在28时中止:[Create virtual table if not exists search_fts using FTS4(name TEXT,tokenize = unicode61 remove_diacritics=2,content = test)] unknown tokenizer
.... 2022 - 07 - 26 11:36:56.539 16176 - 16229/hr. laserline. osis E/hr. laserline. osis. service. sync. SyncServicePresenter:同步错误! DB事务回滚... android.database.sqlite.SQLiteException:未知的tokenizer(代码1)在Android.数据库。sqlite。SQLiteConnection。nativeExecuteForChangedRowCount(原生方法)在Android上。数据库。sqlite。SQLiteConnection。android上的executeForChangedRowCount(SQLiteConnection.java:735)。数据库。sqlite。SQLiteSession。android上的executeForChangedRowCount(SQLiteSession.java:754)。数据库。sqlite。SQLiteStatement。executeUpdateDelete(SQLiteStatement.java:64)at android.数据库。sqlite。SQLite数据库。executeSql(SQLiteDatabase.java:1754)at android.数据库。sqlite。SQLite数据库。androidx上的execSQL(SQLiteDatabase.java:1682)。sqlite。db. framework. FrameworkSQLiteDatabase.在hr.laserline.osis.data.db.LlamaRoomDatabase_Impl$1.AllTables(LlamaRoomDatabase_Impl. java:148)在androidx.房间。RoomOpenHelper。androidx上的onCreate(RoomOpenHelper.java:74)。sqlite。db. framework. FrameworkSQLiteOpenHelper $OpenHelper。android上的onCreate(FrameworkSQLiteOpenHelper.java:177)。数据库。sqlite。SQLiteOpenHelper。getDatabaseLocked(SQLiteOpenHelper.java:333)at android.数据库。sqlite。SQLiteOpenHelper。androidx上的getDataBase(SQLiteOpenHelper.java:238)。sqlite。db. framework. FrameworkSQLiteOpenHelper $OpenHelper。androidx上的getDataableSupportDatabase(FrameworkSQLiteOpenHelper.java:151)。sqlite。db. framework. FrameworkSQLiteOpenHelper。androidx上的getDataBase(FrameworkSQLiteOpenHelper.java:112)。房间。RoomDatabase。androidx上的inTransaction(RoomDatabase.java:706)。房间。RoomDatabase。在hr时的assertNotSuspendingTransaction(RoomDatabase.java:483)。激光线疾病。数据。db.道。参数Dao_Impl. getSyncNumPerChunk(ParameterDao_Impl. java:610)在hr.激光线疾病。数据。储存库。参数库。getSyncNumPerChunk(ParameterRepository.java:72)at hr.激光线疾病。服务。同步SyncServiceInteractor。setNumPerChunk(SyncServiceInteractor.java:62)at hr.激光线疾病。服务。同步SyncServicePresenter。lambda $startSyncWithErp $0 $hr-laserline-osis-service-sync-SyncServicePresenter(SyncServicePresenter.java:98),位于hr.laserline.osis.service.sync.SyncServicePresenter$$ExternalSyntheticLambda2.get(未知源:10)at io.reactivex.rxjava3.internal.operators.observable.ObservableDefer.subscribeActual(ObservableDefer.java:33)at io.reactivex.rxjava3.core.Observable.subscribe(Observable.java:13176)at io.reactivex.rxjava3.internal.operators.observable.ObservableSubscribeOn $
有什么建议吗?

3df52oht

3df52oht1#

这不仅仅是Room,这是FTS 3 -4/unicode 61 tokenizer的一般问题。
简单地说

  • tokenize=unicode61具有Android minSdk = 21要求。
  • tokenize=unicode61 'remove_diacritics=0|1'具有Android minSdk = 21要求。
  • tokenize=unicode61 'remove_diacritics=2'具有Android minSdk = 30要求。

SQLite 3.27.0(从Android API 30开始嵌入)有这一行:
在FTS 3和FTS 5中添加了remove_diacritics=2选项。
请参阅我的blog的完整细节。

相关问题