Библиотека сохраняемости SQLite и комнаты: как объединить условие IN и LIKE?

У меня проблемы с поиском в Google, но, надеюсь, это не слишком сложно для эксперта (или даже среднего уровня).

Есть ли способ найти подстроку в неизвестном количестве множественных условий ИЛИ?

Исходный запрос для Android SQLite Room Persistence DAO:

SELECT country FROM table WHERE country IN (:searchList)

Что, учитывая searchList ['Париж, Франция', 'Берлин, Германия'], переведет в SQL:

SELECT country FROM table WHERE country IN ( 'Paris, France', 'Berlin, Germany' );

И вернется: [«Париж, Франция», «Берлин, Германия»]

Однако я хотел бы иметь возможность искать только по стране. Например, учитывая список searchList ['Франция', 'Германия'], я, к сожалению, не получил результата.

Я понимаю, что следующий SQL-код поможет:

SELECT country FROM table  WHERE country LIKE '%France%' OR country LIKE '%Germany%';

Однако, поскольку я не знаю, сколько элементов будет в searchList, я должен использовать исходный формат:

SELECT country FROM table WHERE country IN (:searchList)

Есть ли способ выполнить указанный выше поиск подстроки в столбце страны?

Большое спасибо за вашу помощь,

Дэн


person danwag    schedule 22.08.2017    source источник
comment
Поскольку androids sqlite (версия) не поддерживает регулярное выражение в поисковом запросе, вы можете вместо этого разделить список (: searchList) на отдельные слова? Пример: stackoverflow.com/questions/41678776/   -  person Emanuel S    schedule 22.08.2017
comment
Я надеялся избежать разделения searchList, потому что тогда мне пришлось бы выполнять несколько вызовов БД - по одному для каждого элемента searchList.   -  person danwag    schedule 22.08.2017


Ответы (1)


Поскольку Androids Sqlite не поставляется с Regex, вам нужно будет разделить список перед поиском.

SQLite IN-Operator сортирует ваш список и использует двоичный поиск, который намного быстрее, чем использование одиночных запросов для этого случая.

Производительность OR vs IN для сравнения скорости (к сожалению, не для пакетных запросов)

SELECT COUNT(*) FROM t_inner WHERE val IN (1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000);
1 row fetched in 0.0032 (1.2679 seconds)

SELECT COUNT(*) FROM t_inner WHERE val = 1000 OR val = 2000 OR val = 3000 OR val = 4000 OR val = 5000 OR val = 6000 OR val = 7000 OR val = 8000 OR val = 9000;
1 row fetched in 0.0026 (1.7385 seconds)
person Emanuel S    schedule 22.08.2017
comment
Спасибо за ваш ответ. Это позор :) Думаю, я добавлю строку страны для каждой записи, чтобы UID был связан как с Берлином, так и с Германией и Германией. - person danwag; 22.08.2017
comment
Да, я знаю, но это Room .. Я использую его для очень больших проектов и пока он стабилен, но это не значит, что он окончен ;-) Есть несколько портов Sqlite, которые поддерживают регулярные выражения. - person Emanuel S; 22.08.2017
comment
Вы можете проверить скорость, если вы получили все результаты или хотя бы по частям, а затем использовать выбор / фильтр. - person Emanuel S; 22.08.2017
comment
Хорошая точка зрения. Я буду следить за обновлениями, но пока дополнительная строка должна помочь. - person danwag; 22.08.2017
comment
Проблема не столько в скорости, никогда не должно быть больше ~ 20 местоположений для поиска, это просто вариативность - я не знаю, сколько местоположений я буду искать, поэтому я не могу создать SQL с правильным количеством OR заранее. - person danwag; 22.08.2017
comment
Тогда я бы порекомендовал выбрать все и фильтровать после. - person Emanuel S; 22.08.2017