В этой статье я объясню, как вы можете обеспечить своего рода полнотекстовый поиск в своем приложении, используя службы, доступные службам App Engine.
В моем конкретном случае использования я не требую большого количества функций, мне просто нужно просто найти строку в различных атрибутах моих сущностей независимо от регистра и возможные специальные символы (такие как è, é,…). Я далеко не эксперт Google Datastore API, но я не нашел простого способа добиться этого напрямую с помощью Java API. Чтобы решить эту проблему, я скопировал часть моих данных в Google Cloud SQL, чтобы использовать возможности полнотекстового поиска MySQL.
Предпосылки
Для решения следующих задач вам необходимо:
- Установите Google AppEngine SDK для Java
- Установите MySQL 5.5
- Учетная запись Google с сервисами AppEngine и Cloud SQL .
- Дополнительно: Eclipse Plugin для разработки, отладки и развертывания моего веб-приложения в GAE.
содержание
В следующих параграфах я объясню основы интеграции Cloud SQL для полнотекстового поиска, но вы можете, если хотите, перейти к:
- полный код приложения: https://github.com/tgrall/gae-full-text-search
- взгляните на работающее приложение: http://gae-fulltext-search.appspot.com/
1. Создание статей сущностей
Начните с создания нескольких простых объектов с некоторыми атрибутами, например, с именем объекта Article, с атрибутами title и body.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
import com.google.appengine.api.datastore.DatastoreService;import com.google.appengine.api.datastore.DatastoreServiceFactory;import com.google.appengine.api.datastore.Entity;//...//... Entity article = new Entity("Article"); article.setProperty("title", "MySQL Tutorial"); article.setProperty("body", "DBMS stands for DataBase ..."); datastore.put(article); article = new Entity("Article"); article.setProperty("title", "Datastore Index Selection and Advanced Search"); article.setProperty("body", "Learn how recent improvements to the query planner ... function in your application"); datastore.put(article); |
Если вы загляните в Datastore API, или даже в JDO или JPA, у вас не будет простого способа найти все статьи, связанные с триатлоном, базой данных или сущностями. Google DataStore не поддерживает предложение где с «ИЛИ» между различными полями; и я не хочу упоминать тот факт, что невозможно игнорировать текстовый случай простым способом.
Вот почему нам нужны некоторые полнотекстовые функции. Некоторые из вас наверняка думают об использовании Apache Lucene, и да, это возможно. Вы можете использовать, например, проект GAELucene: http://code.google.com/p/gaelucene/ . Я использую другой подход, может быть менее продвинутым с точки зрения параметров «индексация / поиск», но достаточным для моего варианта использования:
- Я храню текстовые значения, по которым я хочу выполнить поиск, в Google Cloud SQL и использую полнотекстовые функции MySQL.
2. Создайте таблицу SQL для хранения текстовых значений (в среде разработки)
При использовании Google AppEngine доступ к экземплярам Cloud SQL осуществляется с использованием определенного драйвера и конфигурации, которые мы увидим позже. На данный момент мы все еще находимся в среде разработки, здесь вы должны использовать свой локальный экземпляр MySQL.
В этом конкретном случае использования мы скопируем в таблицу два поля и добавим новый уникальный ключ на основе ключа объекта. Итак, SQL для создания этого:
|
01
02
03
04
05
06
07
08
09
10
11
12
|
CREATE SCHEMA search_values DEFAULT CHARACTER SET utf8 ;USE search_values;CREATE TABLE articles ( entity_key varchar(250), title text, body text, PRIMARY KEY RESULTS_PK (entity_key), FULLTEXT (title,body)) ENGINE=MyISAM DEFAULT CHARSET=utf8; |
Строки 1 и 3 предназначены для создания схемы базы данных и ее использования; Затем сценарий создает таблицу, которая будет содержать копию заголовка и тела от объекта.
3. Настройте среду разработки
Этот раздел представляет собой краткое объяснение документации по облачному SQL: Начало работы: Java
- Скопируйте драйвер MySQL JDBC в каталог SDK Google App Engine в каталоге
/lib/impl/. Вы можете скачать драйвер MySQL JDBC здесь . - В Eclipse выберите свой пакет Java.
- Нажмите « Выполнить» > « Выполнить настройки» .
- Разверните пункт меню Веб-приложение .
- Добавьте следующие строки в панель VM Arguments :
123
-Drdbms.server=local-Drdbms.driver=com.mysql.jdbc.Driver-Drdbms.url=jdbc:mysql://localhost:3306/search_values?user=username&password=password - Нажмите вкладку Classpath .
- Выберите ваш проект и нажмите Add External JARs…
- Перейдите в каталог SDK Google App Engine, затем
lib/implи выберите файл JAR драйвера JDBC. Нажмите Открыть . JAR драйвера указан в разделе « Записи пользователя» . - Нажмите Применить .
Ваша среда разработки готова к использованию вашей локальной базы данных MySQL. Давайте теперь использовать эту базу данных.
4. Используйте свою таблицу MySQL и скопируйте текстовые значения из Google Datastore в MySQL Table
Копировать данные из сущности Datastore в таблицу довольно просто:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
Connection conn = null;try { DriverManager.registerDriver(new AppEngineDriver()); conn = DriverManager.getConnection("jdbc:google:rdbms://[your db instance]/search_values"); conn.setAutoCommit(false); String statement = "REPLACE INTO articles (entity_key, title, body) VALUES( ? , ? , ? )"; PreparedStatement stmt = conn.prepareStatement(statement); DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); Query q = new Query("Article"); PreparedQuery pq = datastore.prepare(q); // loop on each entity and insert the values in the SQL Table for (Entity result : pq.asIterable()) { stmt.setString(1, KeyFactory.keyToString(result.getKey()) ); stmt.setString(2, result.getProperty("title").toString() ); stmt.setString(3, result.getProperty("body").toString() ); stmt.executeUpdate(); conn.commit(); }} catch (SQLException e) { e.printStackTrace();} finally { if (conn != null) try { conn.close(); } catch (SQLException ignore) {}} |
Некоторые специальные вещи здесь, по сравнению со стандартной веб-разработкой Java:
- Я управляю соединением напрямую в своем коде ( я еще не посмотрел, могу ли я использовать источники данных / пул соединений в контексте Google AppEngine )
- Строка # 3: регистрация драйвера AppEngine, отвечающего за управление соединением, особенно работа в -local MySQL- или в производственном режиме -CloudSQL-.
- Строка № 4: Получить соединение. Интересно отметить, что при разработке URL-адрес соединения берется из переменной среды Drdbms.url, которую вы установили ранее. Позже мы увидим, как мы перенесем это в облако. Это волшебная часть AppEngineDriver, которая управляет различными типами соединений Local MySQL или CloudSQL в зависимости от контекста
- После этих строк код довольно прост:
- Получить все сущности Статьи из хранилища данных и цикл
- «Upsert» запись базы данных (СМЕНА СМЕНЫ INTO)
- Строка № 15 хранит ключ сущности в безопасной строке, используя метод KeyFactory.keyToString () .
Если вы хотите протестировать этот код, просто поместите эти строки в сервлет, чтобы «синхронизировать» данные из хранилища данных в таблицу MySQL. Очевидно, этот код предназначен только для изучения и должен быть лучше интегрирован в реальное приложение; начиная с отправки данных в базу данных, когда объекты создаются / обновляются (и удаляются;)). Пример кода, доступного на GitHub, содержит эти методы.
5. Реализуйте метод поиска
Цель состоит в простом возвращении списка сущностей, возвращаемых по простому критерию поиска:
- public Iterable searchEntities (Строковый запрос)
Логика здесь довольно проста:
- Выполнить запрос SQL
- Для каждого результата получите сущность, используя ключ
- Возврат списка сущностей
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
public Iterable searchEntity(String query) { List results = new ArrayList (); Connection conn = null; try { DriverManager.registerDriver(new AppEngineDriver()); conn = DriverManager.getConnection("jdbc:google:rdbms://[your db instance]/search_values"); String statement = "SELECT entity_key FROM articles WHERE MATCH (title,body) AGAINST (? WITH QUERY EXPANSION);"; PreparedStatement stmt = conn.prepareStatement(statement); stmt.setString(1, query); ResultSet rs = stmt.executeQuery(); while (rs.next()) { String keyAsString = rs.getString(1); Entity article = DatastoreServiceFactory.getDatastoreService().get( KeyFactory.stringToKey(keyAsString) ); results.add(article); } } catch (SQLException e) { e.printStackTrace(); } catch (EntityNotFoundException e) { e.printStackTrace(); } finally { if (conn != null) try { conn.close(); } catch (SQLException ignore) {} } return results;} |
В этом методе система подключается к базе данных, а затем выполняет запрос для поиска данных, используя любой тип запроса SQL / MySQL. В этом экзамене я использую полнотекстовую функцию с « С расширением запроса ». Очевидно, что вы можете использовать любой тип SQL-запросов, например, простой оператор LIKE, если этого достаточно для вашего приложения.
С таким подходом, когда я ищу:
- «База данных»: метод возвращает все статьи, касающиеся базы данных, mysql, RDBMS независимо от случая.
- «Index» — метод возвращает все статьи, в которых говорится об индексации / индексировании или поиске.
6. Развертывание в GAE
После того как вы создали свое приложение, активировали и настроили свой экземпляр CloudSQL ( здесь) , вы можете развернуть свое приложение и наслаждаться простым способом использования полнотекстового поиска с GAE.
Вывод
В этой статье я объяснил, как вы можете использовать Google Cloud SQL для простой поддержки запросов полнотекстового поиска на основе полнотекстовой поддержки MySQL.
Фрагменты кода, которыми я поделился в этой статье, действительно просты и не готовы для реального использования, но все же являются хорошей отправной точкой. Например, я использовал это в своем приложении с очередями GAE, чтобы управлять своими индексами для большего объема данных.
Как было сказано ранее, вы можете протестировать приложение онлайн по адресу http://gae-fulltext-search.appspot.com/, а исходный код доступен на GitHub: https://github.com/tgrall/gae-full-text-. поиск
Справка: полнотекстовый поиск Google AppEngine с облачным SQL от нашего партнера по JCG Тугдуала Гралла в блоге Tug’s Blog .