【问题标题】:Android autocomplete with SQLite LIKE works partially带有 SQLite LIKE 的 Android 自动完成功能部分工作
【发布时间】:2014-01-06 08:23:15
【问题描述】:

我的 SQLite 数据库中有一个 Restaurants 表,其中包含以下记录

| Name   | Latin_Name |
+--------+------------+
| Манаки | Manaki     |
+--------+------------+
| Енрико | Enriko     |
+---------------------+

现在我正在做这样的搜索:

来自我的片段:

String selection = DBHelper.COL_NAME + " LIKE ? OR " +
                    DBHelper.COL_LATIN_NAME + " LIKE ?";

String[] selectionArgs = {"%"+term+"%", "%"+term+"%"};

CursorLoader loader = new CursorLoader(getActivity(), 
                               DatabaseContentProvider.REST_CONTENT_URI, 
                               columns, selection, selectionArgs, null);

内容提供者query方法:

 public Cursor query(Uri uri, String[] projection, String selection,
                    String[] selectionArgs, String sortOrder) {

    db = dbHelper.getReadableDatabase();
    SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
    switch(URI_MATCHER.match(uri)){
        case REST_LIST:
            builder.setTables(DBHelper.REST_TABLE);
            break;
        case REST_ID:
            builder.appendWhere(DBHelper.COL_ID + " = "
                    + uri.getLastPathSegment());
            break;
        default:
            throw new IllegalArgumentException("Unsupported URI: " + uri);
    }
    Cursor cursor = builder.query(db, projection, selection, selectionArgs,
            null, null, sortOrder);


    cursor.setNotificationUri(getContext().getContentResolver(), uri);

    return cursor;
}

这么基本的吧?现在问题来了:

如果进来的termen,我可以看到Enriko 餐厅等。

如果我通过了enri,我就再也看不到Enriko了。

Manaki 餐厅也是如此,我可以在 mana 之前看到它,之后(对于 manak 来说,前任)我在结果列表中看不到它。

我在调试我的 ContentProvider 时发现光标是空的,所以我猜应该是数据库级别的问题。

请帮忙。

更新:

考虑到@laalto cmets,我决定对数据库进行一些测试。在我的SQLiteOpenHelperonCreate() 方法中,我仅在表中手动插入了这两条记录,它起作用了。

现在的问题是我必须从assets 文件夹中的json 文件中插入1300 条记录onCreate()。现在我正在解析json 文件,创建一个ArrayList<Restaurant>,然后循环遍历它并为所有1300 个项目为每个对象插入一条记录。

这种插​​入不适用于 SQLite LIKE 方法。

这种填充数据库有什么陷阱吗?

也许我需要更改文件编码(现在是 UTF-8)或者数据库的排序规则,或者可以针对数据库调整来自 JSONObjectgetString()

【问题讨论】:

  • 如何生成数据库中的Latin_Name?考虑可能存在一些不可见但影响LIKE匹配的字符。
  • 当我在桌面 SQLite 应用程序中运行此查询 SELECT * FROM Restaurants where Latin_name LIKE '%enri%' 时,我得到了想要的结果。
  • 好的 - 您可以检查构建器生成的 SQL。例如将builder.query() 替换为builder.buildQuery(),记录查询字符串并使用db.rawQuery() 进行查询。
  • 我试过用rawQuery() 运行这个查询SELECT * FROM Restaurants WHERE (Latin_Name LIKE 'enrik%') 仍然没有
  • 我没有任何新想法,只是怀疑Latin_Name 不仅仅是普通的 ASCII 字符。您可以replaceAll("[^\\p{ASCII}]", "") 删除非ascii。

标签: android sqlite autocomplete sql-like


【解决方案1】:

如果紧急,这里有一个快速而肮脏的解决方案。

2.600 个字符串(1.300 西里尔文 + 1.300 拉丁文)在内存中处理的值非常少:您可以简单地从 SQLite 加载所有值

select name, latin_name from restaurants

然后您可以在 Java 中循环结果集,同时使用 String.contains 方法搜索匹配的字符串。请记住,contains 方法是区分大小写的,因此您应该使用如下内容:

string1.toLowerCase().contains(string2.toLowerCase())

【讨论】:

    【解决方案2】:

    sqlite 文档link

    The LIKE operator does a pattern matching comparison. The operand to the right of the LIKE
    operator contains the pattern and the left hand operand contains the string to 
    match against the pattern. A percent symbol ("%") in the LIKE pattern matches any
    sequence of zero or more characters in the string. An underscore ("_") in the LIKE 
    pattern matches any single character in the string. Any other character matches 
    itself or its lower/upper case equivalent (i.e. case-insensitive matching). 
    (A bug: SQLite only understands upper/lower case for ASCII characters by default. 
    The LIKE operator is case sensitive by default for unicode characters that are
    beyond the ASCII range. For example, the expression 'a' LIKE 'A' is TRUE but 'æ' LIKE 'Æ'   
    is FALSE.)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      • 2013-03-22
      • 1970-01-01
      • 2015-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多