Android Room-未知令牌-Ftsoptions.Tokenizer_unicode61

发布于 2025-02-12 05:51:33 字数 5663 浏览 0 评论 0原文

我正在将FTS4与令牌化器一起删除变节。数据库用房间抽象。

类似:

content

@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 30),但是在较旧版本(IEAPI 25或27)上,我得到了以下错误:

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

官方文档:

“ Unicode61”令牌可以从SQLite版本3.7.13(2012-06-11)开始。 Unicode61的工作非常类似于“简单”,除了它根据Unicode版本6.1中的规则进行简单的Unicode案例折叠,并且识别Unicode空间和标点符号和标点符号,并使用这些字符将其分开。

API和数据库版本:

“在此处输入图像描述”

logcat:

2022-07-26 11:36:36:56.532 16176-16229/hr.laserline.sisis e/sqlitelog:(1)语句在28:[创建虚拟表格,如果不存在search_fts使用search_fts 使用使用fts4(name文本,tokenize = unicode61 remove_diacritics = 2,content = test)]未知令牌

.... ... 2022-07-26 11:36:56.539 16176-16229/hr.laserline.sise e/hr.laserline.sos.service.service.service.sync.sync.syncservicepresenter:同步错误! DB交易回滚... android.database.sqlite.sqliteException:未知令牌(代码1) at android.database.sqlite.sqliteconnection.nativeexecuteforchangedrowcount(本机方法) at android.database.sqlite.sqliteconnection.executeforchangedrowcount(sqliteconnection.java:735) at android.database.sqlite.sqliteessession.executeforchangedrowcount(sqlitesession.java:754) at android.database.sqlite.sqlitestatement.executeupdatedelete(sqlitestatement.java:64) at android.database.sqlite.sqlitedatabase.executesql(sqlitedatabase.java:1754) at android.database.sqlite.sqlitedatabase.execsql(sqlitedatabase.java:1682) at androidx.sqlite.db.framework.frameworksqlitedatabase.execsql(frameworksqlitedatabase.java:265) 在hr.laserline.sis.data.db.llamaroomdatabase_impl $ 1.CREATEALLTABLES(LlamaroomDataBase_Impl.java:148) 在Androidx.Room.Roomopenhelper.Oncreate(Roomopenhelper.java:74) at androidx.sqlite.db.framework.frameworksqliteopenhelper $ openhelper.oncreate(frameworksqlitesqlitesqliteopenhelper.java:177) at android.database.sqlite.sqliteopenhelper.getDatabaselocked(sqliteopenhelper.java:333) at android.database.sqlite.sqliteopenhelper.getWritabledatabase(sqliteopenhelper.java:238) at androidx.sqlite.db.framework.frameworksqlitesqliteopenhelper $ openhelper.getWritablesupportDatabase(frameworksqliteworkssqliteopenhelper.java:151) at androidx.sqlite.db.framework.frameworksqlitepenhelper.getWritabledatabase(FrameworksqliteSqliteSqliteOpenHelper.java:112) 在Androidx.Room.RoomDatabase.Intransaction(RoomDatabase.Java:706) 在Androidx.Room.RoomDatabase.AssertnotsuspendingTransaction(RoomDatabase.java:483) 在hr.laserline.sis.data.dao.dao.parameterdao_impl.getsyncnumperchunk(parameterdao_impl.java:610) 在hr.laserline.sis.data.repositories.parameterrepository.getsyncnumperchunk(parameterrepository.java:72) 在hr.laserline.siser.service.sync.sync.syncserviceinteractor.setnumperchunk(SyncServiceInteractor.java:62) 请访问hr.laserline.siser.service.sync.sync.syncservicepresenter.lambda $ startSyncwitherp $ 0 $ hr-laserline-service-service-service-sync-sync-syncsyncservicepresenter(syncservicepreSenter.java:98) 在hr.laserline.sos.service.sync.sync.syncservicepresenter $$外部灵性lambda2.get(未知来源:10) 在io.reaectivex.rxjava3.internal.operators.Observable.ObservableDefer.SubscribeActual(observabledefer.java:33) 在io.reeactivex.rxjava3.core.observable.subscribe(observable.java:13176) 在io.Reactivex.rxjava3.internal.operators.Observable.Observablesubscribeon $ sisscribetask.run(observablesubscribeon.java:96)) 在io.reeactivex.rxjava3.internal.schedulers.scheduleddirecttask.call(scheduleddirecttask.java:38) 在io.reeactivex.rxjava3.internal.schedulers.scheduleddirecttask.call(scheduleddirecttask.java:25) 在java.util.concurrent.futuretask.run(futuretask.java:266) at Java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1162) at Java.util.concurrent.threadpoolexecutor $ worker.run(threadpoolexecutor.java:636) 在java.lang.thread.run(thread.java:764) 在hr.laserline

有什么建议吗?

I'm using FTS4 with a tokenizer to remove diacritics. The database is abstracted with Room.

Something like:

Content

@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;
    }
}

This results in a SQLite query:

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

Everything works on newer Android versions (i.e. API 30), but on older versions (i.e.API 25 or 27) I get the following error:

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

The official docs:

The "unicode61" tokenizer is available beginning with SQLite version 3.7.13 (2012-06-11). Unicode61 works very much like "simple" except that it does simple unicode case folding according to rules in Unicode Version 6.1 and it recognizes unicode space and punctuation characters and uses those to separate tokens.

API and database version:

enter image description here

Logcat:

2022-07-26 11:36:56.532 16176-16229/hr.laserline.osis E/SQLiteLog: (1) statement aborts at 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: Sync error! Db transaction rollback ...
android.database.sqlite.SQLiteException: unknown tokenizer (code 1)
at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:735)
at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1754)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1682)
at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.execSQL(FrameworkSQLiteDatabase.java:265)
at hr.laserline.osis.data.db.LlamaRoomDatabase_Impl$1.createAllTables(LlamaRoomDatabase_Impl.java:148)
at androidx.room.RoomOpenHelper.onCreate(RoomOpenHelper.java:74)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onCreate(FrameworkSQLiteOpenHelper.java:177)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:333)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:238)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:151)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:112)
at androidx.room.RoomDatabase.inTransaction(RoomDatabase.java:706)
at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.java:483)
at hr.laserline.osis.data.db.dao.ParameterDao_Impl.getSyncNumPerChunk(ParameterDao_Impl.java:610)
at hr.laserline.osis.data.repositories.ParameterRepository.getSyncNumPerChunk(ParameterRepository.java:72)
at hr.laserline.osis.service.sync.SyncServiceInteractor.setNumPerChunk(SyncServiceInteractor.java:62)
at hr.laserline.osis.service.sync.SyncServicePresenter.lambda$startSyncWithErp$0$hr-laserline-osis-service-sync-SyncServicePresenter(SyncServicePresenter.java:98)
at hr.laserline.osis.service.sync.SyncServicePresenter$$ExternalSyntheticLambda2.get(Unknown Source: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$SubscribeTask.run(ObservableSubscribeOn.java:96)
at io.reactivex.rxjava3.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
at io.reactivex.rxjava3.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:25)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
at hr.laserline.osis.utils.SingleTaskExecutor$1.run(SingleTaskExecutor.java:118)

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风柔一江水 2025-02-19 05:51:33

这不仅是房间,这是FTS3-4/Unicode61令牌的一般问题。

只需将

  • 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.0.0 (从Android Api 30嵌入Android Api 30)

将remove_diacritics = 2选项添加到fts3和fts5。

请参阅我的

It's not just Room, this is a general issue of FTS3-4/unicode61 tokenizer.

Simply put

  • tokenize=unicode61 has Android minSdk = 21 requirement.
  • tokenize=unicode61 'remove_diacritics=0|1' has Android minSdk = 21 requirement.
  • tokenize=unicode61 'remove_diacritics=2' has Android minSdk = 30 requirement.

SQLite 3.27.0 (embedded from Android API 30 onwards) has this line:

Added the remove_diacritics=2 option to FTS3 and FTS5.

See my blog for full details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文