@alexvdem

Как наиболее эффективно реализовать выборку из базы данных контактов по условию?

Сабж. Сейчас делаю небольшой проект в свободное время, и понадобилось парсить на сервер некоторые контакты, которые овечают определенным условиям (по адресу Google эккаунта, и по наличию телефона в контакте).
Сейчас для того, чтобы сделать выборку, выполняется что-то вроде этого:
spoiler

if (cursor.getCount() > 0) {

            //Если значение имени и номера контакта больше 0 (то есть они существуют) выбираем
            //их значения в приложение привязываем с соответствующие поля "Имя" и "Номер":
            while (cursor.moveToNext()) {
                String contact_id = cursor.getString(cursor.getColumnIndex( _ID ));
                String name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME));
                int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(HAS_PHONE_NUMBER)));

                cursorraw.moveToNext();
                String contact_id_raw = cursor.getString(cursorraw.getColumnIndex(RAW_ID));
                String userprofile = cursorraw.getString(cursorraw.getColumnIndex(CONTACCOUNT));

                //Получаем имя:
                if (hasPhoneNumber > 0) {

                    output.append("\n Имя: " + name);
                    Cursor phoneCursor = contentResolver.query(PhoneCONTENT_URI, null,
                            Phone_CONTACT_ID + " = ?", new String[] { contact_id }, null);

                    Cursor rawcursor = contentResolver.query(CONTENT_URI_RAW, null,
                            RAW_CONT_ID + " = ?", new String[] { contact_id }, null);

                    rawcursor.moveToFirst();
                    userprofile = rawcursor.getString(rawcursor.getColumnIndex(CONTACCOUNT));
                    output.append("\n Account: " + userprofile);
                  
                    //и соответствующий ему номер:
                    while (phoneCursor.moveToNext()) {
                        phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
                        output.append("\n Телефон: " + phoneNumber);
                        phonesnumbers.add(new String[] {phoneNumber,name,userprofile, contact_id, contact_id_raw});
                    }
                }
                output.append("\n");
            }

            //Полученные данные отображаем с созданном элементе TextView:
            contacts.setText(output);
        }


Т.е. чтобы сделать выборку, программа берет первый контакт, сравнивает его на предмет наличия номера, если номер есть, то вставляем в массив, выводим на экран, потом возвращаемся в начало цикла, и все заново. Т.е. перебирает всю базу, чтобы найти нужный(е) контакт(ы). В общем то этот код хоть и корявый, но работает, вопрос только в том, что это все очень медленно. Если условия будет не два, а десять, а адресная книга будет 2-3 тыс. записей, то задержка обработки будет секунд пять. Что явно заметно.
Вопрос: а есть ли какая то библиотека или стандартная процедура Java, которая бы сразу выборку в массив данных формировала, соответствующий определенным критериям? Что-то вроде
$resarray = mysqli_fetch_all($result); из PHP. Я так понимаю, что
contentResolver.query(); всегда делает выборку по одной строке?
  • Вопрос задан
  • 87 просмотров
Пригласить эксперта
Ответы на вопрос 3
xez
@xez Куратор тега Java
Senior Junior Roo
Java stream API
Ответ написан
azerphoenix
@azerphoenix Куратор тега Java
Java Software Engineer
А почему бы вам не получить List объектов, а далее уже средствами Stream API не проводить выборку?
Тут на самом деле нужно понять насколько сильно вы хотите заморочиться с реализацией. Ведь, можно и elasticsearch поднять, построить индексы и далее уже проводить поиск с его помощью... Хотя, скорее всего для такой задачи elastic будет лишним...
Ответ написан
akaish
@akaish
Стек Java\Android
Список контактов - это SQLite база данных. Можно получить курсор с выборкой, выполнив запрос к базе через ContentResolver. Ну или получить всё содержимое таблички и пройтись с помощью Kotlin расширений к коллекциям, через Java Stream Api, с помощью RxJava или Kotlin Flow или отфильтровать коллекцию с помощью классических средств Java.
Вот ссылка на SO с примером запроса к БД через ContentResolver: https://stackoverflow.com/a/11862598
Не понимаю, почему два ответа по Stream API, в данном вопросе это только один из вариантов получения выборки из уже готового сета, вопрос заключался в оптимизации скорости выборки из базы контактов. Если цикл заменить на стрим, ускорения не будет, лол, потому что все будет упираться в медленный ContentResolver, на получение одного контакта по id тупо большие накладные расходы.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
ПрофСофт Саратов
от 180 000 до 250 000 ₽
Artezio Нижний Новгород
от 100 000 ₽
Artezio Санкт-Петербург
от 120 000 ₽