我正在使用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 $
有什么建议吗?
1条答案
按热度按时间3df52oht1#
这不仅仅是Room,这是FTS 3 -4/unicode 61 tokenizer的一般问题。
简单地说
tokenize=unicode61
具有AndroidminSdk = 21
要求。tokenize=unicode61 'remove_diacritics=0|1'
具有AndroidminSdk = 21
要求。tokenize=unicode61 'remove_diacritics=2'
具有AndroidminSdk = 30
要求。SQLite 3.27.0(从Android API 30开始嵌入)有这一行:
在FTS 3和FTS 5中添加了remove_diacritics=2选项。
请参阅我的blog的完整细节。