【问题标题】:Full Text Search FTS4 error - unable to use function MATCH全文搜索 FTS4 错误 - 无法使用 MATCH 功能
【发布时间】:2023-03-19 12:36:01
【问题描述】:

我正在尝试在我的应用程序中实现 FTS4,该应用程序也使用 Room。根据我阅读的文档和教程,这不是一个非常复杂的设置,但我的查询触发了一个持久性错误,我似乎无法弄清楚。

正如我在 db 检查器中看到的那样,我的 fts 表正在正确创建和填充。此外,在我尝试使用 MATCH 运行任何查询之前,我可以对其运行查询并且没有问题。我得到以下内容

Error retrieving data from table.: unable to use function MATCH in the requested context (code 1 SQLITE_ERROR)

例如,这行得通(尽管使用起来没有意义):

SELECT * FROM community_features JOIN features_fts ON community_features.rowid = features_fts.rowid WHERE features_fts.feature_name LIKE '%TEST%'

但这不是:

SELECT * FROM community_features JOIN features_fts ON community_features.rowid = features_fts.rowid WHERE features_fts.feature_name MATCH '*TEST*'

更新 - 将我的应用与另一个应用进行比较,我注意到他们的 FTS 生成的文件比我的多。在我的数据库检查器中,我可以看到完整的 features_fts 表,但我没有看到其他应用程序中出现的 _docsize、_segdir、_segments 或 _stat 表。我猜这些应该以某种方式自动生成,这就是我的 MATCH 函数不起作用的原因。我是否错过了流程中的某个步骤?

以下是我的文件:

数据库设置

    public class FeatureIndexDBClient {

    private final FeatureIndexDB mDb;
    private static String mDbName;
    private static FeatureIndexDBClient mInstance;

    private FeatureIndexDBClient(Context context, String dbName) {
        if(mDbName == null || !mDbName.equalsIgnoreCase(dbName)) {
            mDbName = dbName;
        }
        mDb = Room.databaseBuilder(context, FeatureIndexDB.class, dbName)
                .addCallback(new RoomDatabase.Callback() {
                    @Override
                    public void onCreate(@NonNull SupportSQLiteDatabase db) {
                        super.onCreate(db);
                        db.execSQL("INSERT INTO features_fts(feature_name) VALUES ('rebuild')");
                    }
                })
                .fallbackToDestructiveMigration()
                .build();
    }

    public static synchronized FeatureIndexDBClient getInstance(Context context, String dbName) {
        if (mInstance == null || mDbName == null || !mDbName.equalsIgnoreCase(dbName)) {
            mInstance = new FeatureIndexDBClient(context, dbName);
        }
        return mInstance;
    }

    public FeatureIndexDB getAppDatabase() {
        return mDb;
    }

    public void close() {
        this.mDb.close();
    }

    public SimpleSQLiteQuery getFeatureFTSQuery() {
        return new SimpleSQLiteQuery("INSERT INTO features_fts(feature_name) SELECT community_features.feature_name FROM community_features");
    }
}

实体:

@Entity(tableName = "community_features")
public class OSCommunityFeature implements Parcelable {

    @NonNull
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "rowid")
    private Long rowId;

    @ColumnInfo(name = "_id")
    private String _id;

    @ColumnInfo(name = "community_id")
    private int communityId;

    @ColumnInfo(name = "feature_id")
    private int featureId;

    @ColumnInfo(name = "feature_type")
    private Integer featureType;

    @ColumnInfo(name = "feature_name")
    private String feature_name;

    public OSCommunityFeature() {

    }

    ... constructors, getters, setters
}



@Entity(tableName = "features_fts")
@Fts4(contentEntity = OSCommunityFeature.class)
public class CommunityFeatureFTS {

    @PrimaryKey
    @ColumnInfo(name = "rowid")
    private Long rowId;

    @ColumnInfo(name = "feature_name")
    private String feature_name;

    public CommunityFeatureFTS() {
    }

    public CommunityFeatureFTS(Long id, String name) {
        this.rowId = id;
        this.feature_name = name;
    }

在从服务器检索数据后填充该表。一旦数据加载到数据库中,我就会调用:

"INSERT INTO features_fts(feature_name) SELECT community_features.feature_name FROM community_features"

我的道如下:

@Dao
public interface FeatureIndexDAO {

// Community Features --------------------------------------------------------------------------

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAllFeatures(List<OSCommunityFeature> features);

@Transaction
@Query("SELECT * FROM community_features")
List<OSCommunityFeature> getAllFeatures();

@RawQuery
boolean setFeatureFTSTable(SupportSQLiteQuery query);

@Query("SELECT * FROM community_features JOIN features_fts ON community_features.rowid = features_fts.rowid WHERE features_fts.feature_name MATCH :searchFor")
List<OSCommunityFeature> searchForFeatures(String searchFor);

分级:

implementation "androidx.room:room-runtime:2.2.6"
annotationProcessor  'android.arch.persistence.room:compiler:2.2.6'

我一直在阅读我能找到的所有内容,但一直在使用 this tutorialthis。我可以从第一个链接下载示例项目,构建它并毫无问题地运行它。我真的说不出有什么不同。我已经来回走了大约一天了。

有人有任何提示或线索可以为我指明正确的方向吗?

【问题讨论】:

    标签: android sqlite full-text-search android-room


    【解决方案1】:

    花了太多时间才弄明白...

    我需要改变

    annotationProcessor  'android.arch.persistence.room:compiler:2.2.6'
    

    到:

    annotationProcessor  'androidx.room:room-compiler:2.2.6'
    

    ??‍♂️

    【讨论】:

      猜你喜欢
      • 2021-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多