Статьи

Использование Sphinx и Java для реализации свободного текстового поиска


Как и было обещано, я собираюсь предоставить статью о том, как мы можем использовать Sphinx с Java для выполнения полнотекстового поиска.
Я начну статью с введения в сфинкса.

Введение в сфинкса

Базы данных постоянно растут и иногда имеют тенденцию хранить около 100 миллионов записей и нуждаются во внешнем решении для выполнения полнотекстового поиска. Я выбрал Sphinx, систему полнотекстового поиска с открытым исходным кодом, распространяемую под лицензией GPL версии 2, для выполнения полнотекстового поиска на таком огромном количестве данных. Как правило, это отдельная поисковая система, предназначенная для предоставления быстрых, эффективных по размеру и соответствующих функций полнотекстового поиска другим приложениям, очень совместимым с базой данных SQL. Так что мой пример будет основан на базе данных MySQL, так как мы не можем создать миллионы данных для оценки реальной мощи Sphinx, у нас будет небольшой объем данных, и я думаю, что это не должно быть проблемой.

Вот несколько уникальных особенностей Sphinx:

  • высокая скорость индексации (до 10 МБ / с на современных процессорах)
  • высокая скорость поиска (среднее количество запросов меньше 0,1 сек для 2-4 ГБ текстовых коллекций)
  • высокая масштабируемость (до 100 ГБ текста, до 100 М документов на одном процессоре)
  • обеспечивает распределенные возможности поиска
  • обеспечивает поиск изнутри MySQL через подключаемый механизм хранения
  • поддерживает булевы, фразы и запросы на близость слов
  • поддерживает несколько полнотекстовых полей для одного документа (до 32 по умолчанию)
  • поддерживает несколько дополнительных атрибутов для каждого документа (например, группы, метки времени и т. д.)
  • изначально поддерживает MySQL (поддерживаются таблицы MyISAM и InnoDB)

Важными функциями, которые были приняты для выполнения полнотекстового поиска, является обеспечение Java API для легкой интеграции с веб-приложением и значительно высокая скорость индексации и поиска со средней скоростью 4-10 МБ / с и 20-30 мс / q @ 5GB, 3.5M docs (wikipedia)

Сфинкс Условия и как это работает

Принципиальная часть сфинкса —
индексатор, Он несет полную ответственность за сбор данных, которые будут доступны для поиска. С точки зрения Сфинкса, данные, которые он индексирует, представляют собой набор структурированных документов, каждый из которых имеет одинаковый набор полей. Это смещено в сторону SQL, где каждая строка соответствует документу, а каждый столбец — полю. Sphinx создает специальную структуру данных, оптимизированную для наших запросов на основе предоставленных данных. Эта структура называется индексом; и процесс построения индекса из данных называется индексацией, а элемент sphinx, который выполняет эти задачи, называется индексатором. Индексатор может выполняться либо из обычного скрипта, либо из интерфейса командной строки. Сфинкс документы равны записям в БД.

  • Документ представляет собой набор текстовых полей и числовых атрибутов + уникальный идентификатор — аналогично строке в БД
  • Набор полей и атрибутов постоянен для индекса — аналогично таблице в БД
  • Поля доступны для поиска по полнотекстовым запросам
  • Атрибуты могут быть использованы для фильтрации, сортировки, группировки

searchd — это второй принцип работы инструментов в составе Sphinx. Это часть системы, которая фактически выполняет поиск; он функционирует как сервер и отвечает за прием запросов, их обработку и возврат набора данных обратно в различные API для клиентских приложений. В отличие от indexer, searchd не предназначен для запуска из обычного сценария или вызова из командной строки, а вместо этого либо как демон, вызываемый из init.d (в системах типа Unix / Linux), либо как служба ( в системах типа Windows). Я собираюсь сосредоточиться на среде Windows, поэтому позже я покажу вам, как мы можем установить sphinx на windows как сервис.

Наконец
поискявляется одним из вспомогательных инструментов в пакете Sphinx. В то время как searchd отвечает за поиск в среде серверного типа, поиск направлен на быстрое тестирование индекса без создания инфраструктуры для подключения к серверу и обработки его ответа. Это будет использоваться только для тестирования sphinx из командной строки и с учетом требований приложения; Сервис searchd будет использоваться для запроса к серверу MySql предварительно созданного индекса.

Установка в Windows

Итак, теперь мы подошли к части установки Sphinx в Windows:

  • Загрузите Sphinx с официального сайта загрузки Sphinx, т.е. http://sphinxsearch.com (я скачал бинарные файлы Win32 с поддержкой MySQL: sphinx-0.9.9-win32.zip)
  • Разархивировав файл в какую-то папку, я разархивировал в C: \ devel \ sphinx-0.9.9-win32 и добавил каталог bin в переменную пути Windows

Ну Сфинкс установлен. Красиво, просто, легко. Позже я расскажу, как настроить индексы и поиск.

Пример приложения

До сих пор я думаю, что весь девиз этой статьи вам понятен, давайте продолжим, чтобы определить наше пример приложения.

Мы все используем адресную книгу для поиска людей, используя их имя или адрес электронной почты, когда мы хотим немедленно направить сообщение электронной почты определенному человеку, людям или списку рассылки. Мы также ищем людей, используя другую основную информацию, такую ​​как псевдоним электронной почты, местоположение офиса, номер телефона и т. Д. Я думаю, что большинство людей на этой планете достаточно знакомы с этим видом поиска, поэтому давайте составим адресную книгу Outlook. как наша примерная схема базы данных. Большинство полей сопоставлены с Microsoft Outlook, единственным дополнительным столбцом является дата присоединения, чтобы мы могли фильтровать наши запросы по датам присоединения сотрудников.

Пример, который я собираюсь привести, будет использовать Sphinx для поиска конкретной записи адреса с помощью свободного текстового поиска, то есть пользователь может свободно вводить что угодно, вот наш экран поиска, параметр поиска DOJ (дата присоединения) по желанию.

sample search screen

Экран не требует пояснений, давайте продолжим и определим нашу базу данных. Как Sphinx хорошо работает с MySQL и MySQL быть свободным также позволяет создавать свои сценарии DB вокруг базы данных MySQL (Те , кто хочет установить MySQL может Dowload его из
http://www.mysql.com )

Давайте создадим пример базы данных «адресную книгу »

mysql> create database addressbook;
Query OK, 1 row affected (0.03 sec)
mysql> use addressbook;
Database changed

Примечание. Поля, определенные в следующих таблицах, предназначены только для изучения и могут не содержать полный набор полей, которые может предоставить адресная книга Microsoft или любое подобное программное обеспечение.

mysql> CREATE TABLE addressbook (
Id int(11) NOT NULL,
FirstName varchar(30) NOT NULL,
LastName varchar(30) NOT NULL,
OfficeId int(11) DEFAULT NULL,
Title varchar(20) DEFAULT NULL,
Alias varchar(20) NOT NULL,
Email varchar(50) NOT NULL,
DOJ date NOT NULL,
PhoneNo varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

mysql> CREATE TABLE CompanyLocations (
Id int(11) NOT NULL,
Location varchar(60) NOT NULL,
Country varchar(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Пришло время поместить некоторые фиктивные данные в таблицу, так что давайте заполним наши таблицы. Наша виртуальная компания «gogs.it» имеет шесть офисов в Индии и Сингапуре, как определено в следующем сценарии вставки.

mysql> insert into CompanyLocations (Id, Location, Country) VALUES (1, 'Tower One, Harbour Front, Singapore', 'SG');
insert into CompanyLocations (Id, Location, Country) VALUES (2, 'DLF Phase 3, Gurgaon, India', 'IN');
insert into CompanyLocations (Id, Location, Country) VALUES (3, 'Hiranandani Gardens, Powai, Mumbai, India', 'IN');
insert into CompanyLocations (Id, Location, Country) VALUES (4, 'Hinjwadi, Pune, India', 'IN');
insert into CompanyLocations (Id, Location, Country) VALUES (5, 'Toll Post, Nagrota, Jammu, India', 'IN');
insert into CompanyLocations (Id, Location, Country) VALUES (6, 'Bani (Kathua), India', 'IN');

Теперь перейдем к реальным вещам … Сфинкс данных будет индексироваться, давайте также заполним это … wooooo

mysql> INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(1,'Aabheer','Kumar',1,'Mr','u534','[email protected]','2008-9-3', '+911234599990');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(2,'Aadarsh','Gupta',6,'Mr','u668','[email protected]','2007-2-23','+911234599991');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(3,'Aachman','Singh',5,'Mr','u2766','[email protected]','2006-12-18','+911234599992');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(4,'Aadesh','Shrivastav',5,'Mr','u3198','[email protected]','2007-11-23','+911234599993');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(5,'Aadi','manav',1,'Mr','u2686','[email protected]','2010-7-20','+911234599994');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(6,'Aadidev','singh',4,'Mr','u572','[email protected]','2010-8-18','+911234599995');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(7,'Aafreen','sheikh',4,'Smt','u1092','[email protected]','2007-7-11','+911234599996');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(8,'Aakar','Sherpa',5,'Mr','u1420','[email protected]','2009-10-3','+911234599997');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(9,'Aakash','Singh',4,'Mrs','u2884','[email protected]','2008-6-11','+911234599998');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(10,'Aalap','Singhania',4,'Mrs','u609','[email protected]','2010-10-8','+911234599999');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(11,'Aandaleeb','mahajan',1,'Smt','u131','[email protected]','2010-10-21','+911234580001');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(12,'Mamata','kumari',5,'Sh','u2519','[email protected]','2009-6-12','+911234580002');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(13,'Mamta','sharma',6,'Smt','u4123','[email protected]','2009-2-8','+911234580003');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(14,'Manali','singh',6,'Mr','u1078','[email protected]','2008-6-14','+911234580004');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(15,'Manda','saxena',1,'Mrs','u196','[email protected]','2010-9-4','+911234580005');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(16,'Salila','shetty',3,'Miss','u157','[email protected]','2009-11-15','+911234580006');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(17,'Salima','happy',3,'Mrs','u3445','[email protected]','2006-7-14','+911234580007');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(18,'Salma','haik',5,'Sh','u4621','[email protected]','2008-6-23','+911234580008');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(19,'Samita','patil',3,'Smt','u3156','[email protected]','2006-6-7','+911234580009');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(20,'Sameena','sheikh',5,'Mrs','u952','[email protected]','2008-8-13','+911234580010');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(21,'Ranita','gupta',5,'Mrs','u2664','[email protected]','2008-10-20','+911234580011');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(22,'Ranjana','sharma',1,'Sh','u3085','[email protected]','2010-6-21','+911234580012');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(23,'Ranjini','singh',6,'Mrs','u4200','[email protected]','2007-4-13','+911234580013');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(24,'Ranjita','vyapari',2,'Smt','u1109','[email protected]','2008-1-22','+911234580014');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(25,'Rashi','gupta',6,'Mrs','u3492','[email protected]','2006-2-2','+911234580015');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(26,'Rashmi','sehgal',3,'Mr','u3248','[email protected]','2008-9-9','+911234580016');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(27,'Rashmika','sexy',1,'Mrs','u4599','[email protected]','2009-3-12','+911234580017');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(28,'Rasika','dulari',3,'Smt','u2089','[email protected]','2009-1-24','+911234580018');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(29,'Dilber','lover',6,'Mr','u4241','[email protected]','2007-10-11','+911234580019');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(30,'Dilshad','happy',1,'Mr','u1564','[email protected]','2007-4-8','+911234580020');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(31,'Dipali','lights',5,'Sh','u1127','[email protected]','2006-11-1','+911234580021');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(32,'Dipika','lamp',1,'Sh','u2271','[email protected]','2010-12-17','+911234580022');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(33,'Dipti','brightness',5,'Smt','u422','[email protected]','2010-9-25','+911234580023');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(34,'Disha','singh',3,'Sh','u4604','[email protected]','2006-5-2','+911234580024');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(35,'Maadhav','Krishna',1,'Miss','u2561','[email protected]','2007-11-6','+911234580025');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(36,'Maagh','month',5,'Miss','u874','[email protected]','2008-5-8','+911234580026');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(37,'Maahir','Skilled',4,'Mr','u3372','[email protected]','2007-8-4','+911234580027');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(38,'Maalolan','Ahobilam',5,'Mrs','u3498','[email protected]','2007-7-9','+911234580028');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(39,'Maandhata','King',1,'Smt','u2089','[email protected]','2009-9-3','+911234580029');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(40,'Maaran','Brave',2,'Miss','u4020','[email protected]','2008-4-5','+9112345606001');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(41,'Maari','Rain',2,'Sh','u3593','[email protected]','2007-12-5','+9112345606002');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(42,'Madan','Cupid',4,'Mrs','u795','[email protected]','2007-11-11','+9112345606003');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(43,'Madangopal','Krishna',3,'Sh','u438','[email protected]','2007-2-19','+9112345606004');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(44,'sahil','gogna',1,'Sh','u2273','[email protected]','2007-10-7','+9112345606005');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(45,'nikhil','gogna',2,'Mr','u1240','[email protected]','2009-9-14','+9112345606006');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(46,'amit','gogna',5,'Sh','u3879','[email protected]','2006-2-8','+9112345606007');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(47,'krishan','gogna',4,'Miss','u3632','[email protected]','2010-9-20','+9112345606008');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(48,'anil','kashyap',4,'Smt','u3939','[email protected]','2010-3-15','+9112345606009');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(49,'sunil','kashyap',5,'Mrs','u3493','[email protected]','2008-3-16','+9112345606010');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(50,'sandy','singh',6,'Mrs','u4691','[email protected]','2009-6-2','+9112345606011');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(51,'vishal','kapoor',3,'Mr','u1087','[email protected]','2010-5-13','+9112345606012');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(52,'bala','ji',5,'Mrs','u4762','[email protected]','2007-8-9','+9112345606013');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(53,'karan','sarin',4,'Miss','u3030','[email protected]','2008-4-8','+9112345606014');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(54,'abhishek','kumar',4,'Miss','u1093','[email protected]','2008-12-21','+9112345605001');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(55,'babu','the',1,'Miss','u1055','[email protected]','2008-7-2','+9112345506001');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(56,'sandeep','gainda',3,'Miss','u1320','[email protected]','2010-5-14','+9112345606301');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(57,'dheeraj','kumar',3,'Miss','u3685','[email protected]','2007-10-14','+9112345606091');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(58,'dharmendra','chauhan',1,'Smt','u3235','[email protected]','2008-8-1','+9112345806001');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(59,'max','alan',3,'Smt','u3465','[email protected]','2009-5-5','+9112345608011');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(60,'hidayat','khan',3,'Smt','u958','[email protected]','2007-11-18','+911234599101');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(61,'himnashu','singh',4,'Miss','u2027','[email protected]','2008-3-2','+911234599102');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(62,'dinesh','kumar',6,'Sh','u3233','[email protected]','2008-5-9','+911234599103');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(63,'toshi','prakash',1,'Mr','u3766','[email protected]','2010-9-17','+911234599104');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(64,'niti','puri',3,'Mr','u3575','[email protected]','2009-11-15','+911234599105');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(65,'pawan','tikki',3,'Sh','u3919','[email protected]','2006-3-19','+911234599106');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(66,'gaurav','sharma',2,'Sh','u413','[email protected]','2010-4-2','+911234599107');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(67,'himanshu','verma',2,'Mrs','u4732','[email protected]','2009-3-20','+911234599108');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(68,'priyanshu','verma',3,'Sh','u183','[email protected]','2010-8-12','+911234599109');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(69,'nitika','luthra',2,'Mrs','u4259','[email protected]','2010-7-12','+911234599110');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(70,'neeru','gogna',2,'Sh','u1633','[email protected]','2010-6-23','+91532110000');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(71,'bindu','gupta',1,'Sh','u1859','[email protected]','2006-11-10','+91532110001');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(72,'gurleen','bakshi',5,'Miss','u1423','[email protected]','2007-7-1','+91532110003');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(73,'rahul','gupta',3,'Sh','u1223','[email protected]','2009-8-11','+91532110004');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(74,'jagdish','salgotra',3,'Mr','u12','[email protected]','2008-5-19','+91532110005');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(75,'vikas','sharma',3,'Smt','u465','[email protected]','2006-6-2','+91532110006');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(76,'poonam','mahendra',2,'Sh','u1744','[email protected]','2009-12-2','+91532110007');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(77,'pooja','kulkarni',3,'Mrs','u1903','[email protected]','2008-10-6','+91532110008');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(78,'priya','mahajan',6,'Sh','u4205','[email protected]','2010-8-5','+91532110009');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(79,'manoj','zerger',1,'Mrs','u3369','[email protected]','2009-12-4','+91532110010');
INSERT INTO AddressBook(Id, FirstName, LastName, OfficeId, Title, Alias, Email, DOJ, PhoneNo) VALUES
(80,'mohan','master',5,'Mr','u2841','[email protected]','2010-10-7','+91532110011');

Обратите внимание, что приведенные выше данные о сотрудниках — это только данные * только данные *, которые я создал с помощью небольшой java-программы, использующей генераторы случайных чисел и считывающей некоторые имена, поэтому вы можете столкнуться с ошибками в заголовках ?

Далее мы создадим процедуру, которую будем использовать из Java, чтобы получить записи, которые мы только что вставили.

DROP PROCEDURE IF EXISTS search_address_book;
CREATE PROCEDURE search_address_book(IN address_ids VARCHAR(1000) )
BEGIN
DECLARE search_address_query VARCHAR(2000) DEFAULT '';
SET address_ids = CONCAT('\'', REPLACE(address_ids, ',', '\',\''), '\'');
SET search_address_query = CONCAT(search_address_query, ' select ab.Id as Id , ab.FirstName as FName, ab.LastName as LName, cl.Location as Location, ab.Title as Title, ab.Alias as Alias, ab.Email as Email, ab.DOJ as DOJ, ab.PhoneNo as PhoneNo ' );
SET search_address_query = CONCAT(search_address_query, ' from AddressBook ab left join CompanyLocations cl on ab.OfficeId=cl.Id ');
SET search_address_query = CONCAT(search_address_query, ' where ab.id IN (', address_ids ,') ');
SET @statement = search_address_query;
PREPARE dynquery FROM @statement;
EXECUTE dynquery;
DEALLOCATE PREPARE dynquery;
END;

# To get records for ids 1, 6 and 7, we run following commands:
call search_address_book('1,6,7');

Настройка Sphinx

Оказалось, что настроить sphinx не так уж сложно, но мне было трудно найти инструкции в Интернете, поэтому я опубликую свои шаги здесь.

По умолчанию Sphinx ищет файл конфигурации ‘sphinx.co.in’, который идет с индексами и другим материалом, позволяет создавать и определять источник и индекс для нашего примера приложения

addressbook.conf (чтение между строк)

#############################################################################
## data source definition
#############################################################################

source addressBookSource
{

## SQL settings for 'mysql' ##

type = mysql

# some straightforward parameters for SQL source types
sql_host = localhost
sql_user = root
sql_pass = root
sql_db = addressbook
sql_port = 3306 # optional, default is 3306


# pre-query, executed before the main fetch query
sql_query_pre = SET NAMES utf8

# main document fetch query, integer document ID field MUST be the first selected column
sql_query = \
select ab.Id as Id , ab.FirstName as FName, ab.LastName as LName, cl.Location as Location, \
ab.Title as Title, ab.Alias as Alias, ab.Email as Email, UNIX_TIMESTAMP(ab.DOJ) as DOJ, ab.PhoneNo as PhoneNo \
from AddressBook ab left join CompanyLocations cl on ab.OfficeId=cl.Id

sql_attr_timestamp = DOJ

# document info query, ONLY for CLI search (ie. testing and debugging) , optional, default is empty must contain $id macro and must fetch the document by that id
sql_query_info = SELECT * FROM AddressBook WHERE id=$id

}

#############################################################################
## index definition
#############################################################################

# local index example, this is an index which is stored locally in the filesystem

index addressBookIndex

{
# document source(s) to index
source = addressBookSource

# index files path and file name, without extension, make sure you have this folder
path = C:\devel\sphinx-0.9.9-win32\data\addressBookIndex

# document attribute values (docinfo) storage mode
docinfo = extern

# memory locking for cached data (.spa and .spi), to prevent swapping
mlock = 0

morphology = none

# make sure this file exists
exceptions =C:\devel\sphinx-0.9.9-win32\data\exceptions.txt

enable_star = 1

}



#############################################################################
## indexer settings
#############################################################################

indexer
{
# memory limit, in bytes, kiloytes (16384K) or megabytes (256M)
# optional, default is 32M, max is 2047M, recommended is 256M to 1024M
mem_limit = 32M

# maximum IO calls per second (for I/O throttling)
# optional, default is 0 (unlimited)
#
# max_iops = 40


# maximum IO call size, bytes (for I/O throttling)
# optional, default is 0 (unlimited)
#
# max_iosize = 1048576


# maximum xmlpipe2 field length, bytes
# optional, default is 2M
#
# max_xmlpipe2_field = 4M


# write buffer size, bytes
# several (currently up to 4) buffers will be allocated
# write buffers are allocated in addition to mem_limit
# optional, default is 1M
#
# write_buffer = 1M
}

#############################################################################
## searchd settings
#############################################################################

searchd
{
# hostname, port, or hostname:port, or /unix/socket/path to listen on
listen = 9312

# log file, searchd run info is logged here
# optional, default is 'searchd.log'
log = C:\devel\sphinx-0.9.9-win32\data\log\searchd.log

# query log file, all search queries are logged here
# optional, default is empty (do not log queries)
query_log = C:\devel\sphinx-0.9.9-win32\data\log\query.log

# client read timeout, seconds
# optional, default is 5
read_timeout = 5

# request timeout, seconds
# optional, default is 5 minutes
client_timeout = 300

# maximum amount of children to fork (concurrent searches to run)
# optional, default is 0 (unlimited)
max_children = 30

# PID file, searchd process ID file name
# mandatory
pid_file = C:\devel\sphinx-0.9.9-win32\data\log\searchd.pid

# max amount of matches the daemon ever keeps in RAM, per-index
# WARNING, THERE'S ALSO PER-QUERY LIMIT, SEE SetLimits() API CALL
# default is 1000 (just like Google)
max_matches = 1000

# seamless rotate, prevents rotate stalls if precaching huge datasets
# optional, default is 1
seamless_rotate = 1

# whether to forcibly preopen all indexes on startup
# optional, default is 0 (do not preopen)
preopen_indexes = 0

}

# --eof--

Как только конфигурация завершена, пора индексировать наши sql-данные, команда для использования будет ‘indexer’, как показано ниже.

C:\devel\sphinx-0.9.9-win32\bin>indexer.exe --all --config C:\devel\sphinx-0.9.9-win32\addressbook.conf

CONSOLE:

Sphinx 0.9.9-release (r2117)
Copyright (c) 2001-2009, Andrew Aksyonoff

using config file 'C:\devel\sphinx-0.9.9-win32\addressbook.conf'...
indexing index 'addressBookIndex'...
collected 80 docs, 0.0 MB
sorted 0.0 Mhits, 100.0% done
total 80 docs, 5514 bytes
total 0.057 sec, 96386 bytes/sec, 1398.43 docs/sec
total 2 reads, 0.000 sec, 3.5 kb/call avg, 0.0 msec/call avg
total 7 writes, 0.000 sec, 2.5 kb/call avg, 0.0 msec/call avg

Примечание. Как я уже говорил ранее, Sphinx создает 1 документ для каждой строки, так как у нас было 80 строк в базе данных, поэтому в общей сложности создано 80 документов. Времени тоже очень и очень мало, поверьте мне, я пробовал с полмиллиона строк, и это заняло около 3-4 секунд ? круто, не правда ли?

Как только индекс закончится, давайте попробуем поискать несколько записей. Утилита для поиска — «поиск». Ok Sphinx maharaj
* пожалуйста, найдите сотрудника с псевдонимом u4732

C:\devel\sphinx-0.9.9-win32\bin>search.exe --config C:\devel\sphinx-0.9.9-win32\addressbook.conf u4732

CONSOLE:
Sphinx 0.9.9-release (r2117)
Copyright (c) 2001-2009, Andrew Aksyonoff

using config file 'C:\devel\sphinx-0.9.9-win32\addressbook.conf'...
index 'addressBookIndex': query 'u4732 ': returned 1 matches of 1 total in 0.001 sec

displaying matches:
1. document=67, weight=1, doj=Fri Mar 20 00:00:00 2009
Id=67
FirstName=himanshu
LastName=verma
OfficeId=2
Title=Mrs
Alias=u4732
[email protected]
DOJ=2009-03-20
PhoneNo=+911234599108

words:
1. 'u4732': 1 documents, 1 hits

words:
1. 'u4732': 1 documents, 1 hits

Как вы можете видеть выше, это уникальная запись для Химаншу.

Примечание: вы видите много информации для результата, это из-за следующей строки в нашем файле конфигурации

sql_query_info = SELECT * FROM AddressBook WHERE id = $ id

Если вы хотите видеть меньше столбцов, вам нужно изменить sql_query_info в файле конфигурации. Давайте попробуем другой поиск, сфинкс махарадж
*, скажите, пожалуйста, во всех рядах есть гурлин или тоши.

C:\devel\sphinx-0.9.9-win32\bin>search.exe --config C:\devel\sphinx-0.9.9-win32\addressbook.conf --any toshi  gurleen

CONSOLE:
displaying matches:
1. document=63, weight=2, doj=Fri Sep 17 00:00:00 2010
Id=63
FirstName=toshi
LastName=prakash
OfficeId=1
Title=Mr
Alias=u3766
[email protected]
DOJ=2010-09-17
PhoneNo=+911234599104
2. document=72, weight=2, doj=Sun Jul 01 00:00:00 2007
Id=72
FirstName=gurleen
LastName=bakshi
OfficeId=5
Title=Miss
Alias=u1423
[email protected]
DOJ=2007-07-01
PhoneNo=+91532110003

Ровно две записи были возвращены, и это то, что мы ожидали.

The following special operators and modifiers can be used when using the extended matching mode:
operator OR:
nikhil | sahil
operator NOT:
hello -sandy
hello !sandy
field search operator:
@Email [email protected]
For a complete set of search features , I advise you to go through http://sphinxsearch.com/docs/manual-0.9.9.html#searching link.

Sphinx как служба Windows

Теперь наша главная цель — использовать sphinx с JAVA API, поэтому давайте перейдем к этому сейчас, прежде чем java сможет использовать всю мощь Sphinx, нам нужно запустить ‘searchd’ как службу windows, чтобы наша java программа могла подключиться к поисковику sphinx.

Давайте установим Sphinx в качестве службы Windows, чтобы наша Java-программа могла использовать этот демон-сервис для запроса только что созданного индекса, команда:

C:\devel\sphinx-0.9.9-win32\bin>searchd.exe --install  --config C:\devel\sphinx-0.9.9-win32\addressbook.conf --servicename  --port 9312 SphinxSearch

CONSOLE:
Sphinx 0.9.9-release (r2117)
Copyright (c) 2001-2009, Andrew Aksyonoff

Installing service...
Service 'SphinxSearch' installed succesfully.

Что ж, теперь sphinx готов обслуживать нас через порт 9312.

Примечание. Если вы попытаетесь установить Sphinx без прав администратора, вы можете получить следующие сообщения об ошибках.

C:\devel\sphinx-0.9.9-win32\bin>searchd.exe --install  --config C:\devel\sphinx-0.9.9-win32\addressbook.conf --servicename  --port 9312 SphinxSearch

CONSOLE:
Installing service...
FATAL: OpenSCManager() failed: code=5, error=Access is denied.

После этого вы можете запустить сервис как:

c:\>sc start SphinxSearch (or alternatively from the services screen, start 'services.msc' in windows Run)
If some how you want to delete the service , use c:\>sc delete SphinxSearch

Давайте создадим адаптер для извлечения данных из базы данных.

package it.gogs.sphinx.util;

import it.gogs.sphinx.AddressBoook;
import it.gogs.sphinx.exception.AddressBookBizException;
import it.gogs.sphinx.exception.AddressBookTechnicalException;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

/**
* Adapter to fetch data from the database.
*
* @author Munish Gogna
*
*/
public class AddressBookAdapter {

private static Logger logger = Logger.getLogger(AddressBookAdapter.class);

private AddressBookAdapter() {
// use in static way..
}

private static Connection getConnection()
throws AddressBookTechnicalException {
String userName = "root";
String password = "root";
String url = "jdbc:mysql://localhost/addressbook";
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
return DriverManager.getConnection(url, userName, password);
} catch (Exception e) {
throw new AddressBookTechnicalException("could not get connection");
}
}

public static List getAddressBookList(List addressIds)
throws AddressBookTechnicalException, AddressBookBizException {

List addressBoookList = new ArrayList();

if (addressIds == null || addressIds.size() == 0){
logger.error("AddressIds was null or empty, returning empty list");
return addressBoookList;
}


Connection connection = null;
CallableStatement callableStatement = null;
try {
connection = getConnection();
callableStatement = connection.prepareCall("{ call search_address_book(?)}");
callableStatement.setString(1, Utils.toCommaString(addressIds));
callableStatement.execute();
ResultSet resultSet = callableStatement.getResultSet();
prepareResults(resultSet, addressBoookList);
connection.close();
} catch (SQLException e) {
logger.error("Problem connecting MYSQL - " + e.getMessage());
throw new AddressBookTechnicalException(e.getMessage());
} catch (AddressBookTechnicalException e) {
logger.error("Problem connecting MYSQL - " + e.getMessage());
throw e;
} finally{
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
logger.error("Problem closing conection - " + e.getMessage());
e.printStackTrace();
}
}
}

return addressBoookList;
}

private static void prepareResults(ResultSet resultSet,
List addressBoookList) throws SQLException {
AddressBoook addressBoook;
while (resultSet.next()) {
addressBoook = new AddressBoook();
addressBoook.setAlias(resultSet.getString("Alias"));
addressBoook.setEmail(resultSet.getString("Email"));
addressBoook.setfName(resultSet.getString("FName"));
addressBoook.setlName(resultSet.getString("LName"));
addressBoook.setOfficeLocation(resultSet.getString("Location"));
addressBoook.setPhoneNo(resultSet.getString("PhoneNo"));
addressBoook.setTitle(resultSet.getString("Title"));
addressBoook.setDateOfJoining(resultSet.getDate("DOJ"));
addressBoook.setId(resultSet.getLong("Id"));

addressBoookList.add(addressBoook);
}
}
}

Затем мы создаем SphinxInstance, который проанализирует ключевые слова и диапазон дат и предоставит нам список идентификаторов, соответствующих поисковому запросу.

package it.gogs.sphinx.util;

import it.gogs.sphinx.DateRange;
import it.gogs.sphinx.SearchCriteria;
import it.gogs.sphinx.api.SphinxClient;
import it.gogs.sphinx.api.SphinxException;
import it.gogs.sphinx.api.SphinxMatch;
import it.gogs.sphinx.api.SphinxResult;
import it.gogs.sphinx.exception.AddressBookBizException;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
/**
* Instance that will parse our free text and provide the results.
*

* Note: Make sure that 'searchd' is up and running before you use this class
* @author Munish Gogna
*
*/
public class SphinxInstance {

private static String SPHINX_HOST = "localhost";
private static String SPHINX_INDEX = "addressBookIndex";
private static int SPHINX_PORT = 9312;

private static SphinxClient sphinxClient;
private static Logger logger = Logger.getLogger(SphinxInstance.class);

static {
sphinxClient = new SphinxClient(SPHINX_HOST, SPHINX_PORT);
}

public static List getAddressBookIds(SearchCriteria criteria)
throws AddressBookBizException, SphinxException {
List addressIdsList = new ArrayList();

try {
if (Utils.isNull(criteria)) {
logger.error("criteria is null");
throw new AddressBookBizException("criteria is null");
}

if (Utils.isNull(criteria.getKeywords())) {
logger.error("keyword is a required field");
throw new AddressBookBizException("keyword is a required field");
}

DateRange dateRange = criteria.getDateRage();
if (!Utils.isNull(dateRange)) {
if (Utils.isDateRangeValid(dateRange)) {
// this is to filter results based on joining dates if they are provided
sphinxClient.SetFilterRange("DOJ", getTimeInSeconds(dateRange.getFromDate()),
getTimeInSeconds(dateRange.getToDate()), false);
} else {
logger.error(" fromDate/toDate should not be empty and 'fromDate' should be less than equal to 'toDate'");
throw new AddressBookBizException("fromDate/toDate should not be empty and 'fromDate' should be less than equal to 'toDate'");
}
}
sphinxClient.SetMatchMode(SphinxClient.SPH_MATCH_EXTENDED2);
sphinxClient.SetSortMode(SphinxClient.SPH_SORT_RELEVANCE, "");
SphinxResult result = sphinxClient.Query(buildSearchQuery(criteria), SPHINX_INDEX, "buidling query for address book search");

SphinxMatch[] matches = result.matches;

for (SphinxMatch match : matches) {
addressIdsList.add(String.valueOf(match.docId));
}

} catch (SphinxException e) {
throw e;
} catch (AddressBookBizException e) {
throw e;
}

logger.info("Total record(s):" + addressIdsList.size());
return addressIdsList;

}

private static long getTimeInSeconds(Date time) {
return time.getTime()/1000;
}

private static String buildSearchQuery(SearchCriteria criteria)
throws AddressBookBizException {

String keywords[] = criteria.getKeywords().split(" ");
StringBuilder searchFor = new StringBuilder();
for (String key : keywords) {
if (!Utils.isEmpty(key)) {
searchFor.append(key);
if (searchFor.length() > 1) {
searchFor.append("*|*");
}
}

}
searchFor.delete(searchFor.lastIndexOf("|*"), searchFor.length());
StringBuilder queryBuilder = new StringBuilder();
String query = searchFor.toString();
queryBuilder.append("@FName *" + query + " | ");
queryBuilder.append("@LName *" + query + " | ");
queryBuilder.append("@Title *" + query + " | ");
queryBuilder.append("@Location *"+ query + " | ");
queryBuilder.append("@Alias *" + query + " | ");
queryBuilder.append("@Email *" + query + " | ");
queryBuilder.append("@PhoneNo *" + query);

logger.info("Sphinx Query: " + queryBuilder.toString());
return queryBuilder.toString();
}

}

Вот интерфейс, который я представлю внешнему миру (в моей будущей статье я представлю этот интерфейс как веб-сервис)

import it.gogs.sphinx.AddressBoook;
import it.gogs.sphinx.SearchCriteria;
import it.gogs.sphinx.api.SphinxException;
import it.gogs.sphinx.exception.AddressBookBizException;
import it.gogs.sphinx.exception.AddressBookTechnicalException;

import java.util.List;

/**
*
* @author Munish Gogna
*
*/
public interface AddressBook {

/**
* Returns the list of AddressBook objects based on search criteria.
*
* @param criteria
* @throws AddressBookTechnicalException
* @throws AddressBookBizException
* @throws SphinxException
*/
public List getAddressBookList(SearchCriteria criteria)
throws AddressBookTechnicalException, AddressBookBizException,
SphinxException;

}

и вот класс реализации для того же.

package it.gogs.sphinx.addressbook.impl;

import java.util.List;

import it.gogs.sphinx.AddressBoook;
import it.gogs.sphinx.SearchCriteria;
import it.gogs.sphinx.addressbook.AddressBook;
import it.gogs.sphinx.api.SphinxException;
import it.gogs.sphinx.exception.AddressBookBizException;
import it.gogs.sphinx.exception.AddressBookTechnicalException;
import it.gogs.sphinx.util.AddressBookAdapter;
import it.gogs.sphinx.util.SphinxInstance;

/**
* Implementation for our Address Book example
*
* @author Munish Gogna
*
*/
public class AddressBookImpl implements AddressBook{

public List getAddressBookList(SearchCriteria criteria)
throws AddressBookTechnicalException, AddressBookBizException,
SphinxException {

List addressIds= SphinxInstance.getAddressBookIds(criteria);
return AddressBookAdapter.getAddressBookList(addressIds);

}
}

Хорошо, пока все хорошо, давайте теперь запустим несколько тестов …………

package it.gogs.sphinx.test;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import it.gogs.sphinx.AddressBoook;
import it.gogs.sphinx.DateRange;
import it.gogs.sphinx.SearchCriteria;
import it.gogs.sphinx.addressbook.AddressBook;
import it.gogs.sphinx.addressbook.impl.AddressBookImpl;
import it.gogs.sphinx.api.SphinxException;
import it.gogs.sphinx.exception.AddressBookBizException;
import it.gogs.sphinx.exception.AddressBookTechnicalException;
import junit.framework.TestCase;

/**
*
* @author Munish Gogna
*
*/
public class AddressBookTest extends TestCase {

private AddressBook addressBook;

@Override
protected void setUp() throws Exception {
super.setUp();
addressBook = new AddressBookImpl();
}

@Override
protected void tearDown() throws Exception {
super.tearDown();
}

/** this should be a unique record for Himanshu */
public void test_search_for_himanshu() throws Exception {
SearchCriteria criteria = new SearchCriteria();
// remember the first 'search' example??
criteria.setKeywords("u4732");
List addressList = addressBook.getAddressBookList(criteria);
assertTrue(addressList.size() == 1);
assertTrue("expecting himanshu here", "himanshu".equals(addressList.get(0).getfName()));
}

/** only two employees have name gurleen or toshi */
public void test_search_for_gurleen_or_toshi() throws Exception {
SearchCriteria criteria = new SearchCriteria();
// remember the second 'search' example??
criteria.setKeywords("gurleen toshi");
List addressList = addressBook.getAddressBookList(criteria);
assertTrue(addressList.size() == 2);
assertTrue("expecting toshi here", "toshi".equals(addressList.get(0).getfName()));
assertTrue("expecting gurleen here", "gurleen".equals(addressList.get(1).getfName()));
}

/** there are 16 people from jammu location */
public void test_search_for_people_from_jammu_location() throws Exception {
SearchCriteria criteria = new SearchCriteria();
criteria.setKeywords("jammu");
List addressList = addressBook.getAddressBookList(criteria);
assertTrue(addressList.size() == 16);
}

/** only Aalap, Manda and nitika are having title as Mrs and joined in 2010 */
public void test_joined_in_2010_with_title_Mrs() throws Exception {

DateRange dateRange = new DateRange();

GregorianCalendar calendar1 = new GregorianCalendar();
calendar1.set(Calendar.YEAR, 2010);
calendar1.set(Calendar.MONTH, Calendar.JANUARY);
calendar1.set(Calendar.DAY_OF_MONTH, 1);

dateRange.setFromDate(calendar1.getTime());

GregorianCalendar calendar2 = new GregorianCalendar();
calendar2.set(Calendar.YEAR, 2010);
calendar2.set(Calendar.MONTH, Calendar.DECEMBER);
calendar2.set(Calendar.DAY_OF_MONTH, 31);
dateRange.setToDate(calendar2.getTime());

SearchCriteria criteria = new SearchCriteria();
criteria.setKeywords("Mrs");
criteria.setDateRage(dateRange);

List addressList = addressBook.getAddressBookList(criteria);
assertTrue("expecting 3 records here", addressList.size() == 3);

}

/** should get a business exception here */
public void test_without_specifying_keywords(){
SearchCriteria criteria = new SearchCriteria();
//criteria.setKeywords("Mrs");
try {
addressBook.getAddressBookList(criteria);
} catch (Exception e) {
assertTrue(e instanceof AddressBookBizException);
assertTrue(e.getMessage().indexOf("keyword is a required field") >-1);
}
}
}

Как мы обновляем Индекс после изменения базы данных?

Для таких требований мы можем установить два источника и два индекса, с одним «основным» индексом для данных, который изменяется редко (если когда-либо), и одним «дельта» для новых документов. Данные в первый раз попадут в «основной» индекс, а вновь вставленные записи адресной книги перейдут в «дельту». Дельта-индекс может затем очень часто переиндексироваться, и документы можно сделать доступными для поиска в считанные минуты.

Также одна вещь, которую можно извлечь из этой статьи, это когда демон ‘searchd’ запущен, мы не можем индексировать данные обычным способом, мы должны использовать опцию —rotate в таких случаях. Для некоторых приложений, где есть своевременное пакетное обновление данных,
мы можем настроить некоторые задания cron для переиндексации наших документов в Sphinx, как показано ниже.

C:\devel\sphinx-0.9.9-win32\bin>indexer.exe --all --config C:\devel\sphinx-0.9.9-win32\addressbook.conf --rotate

Капсула

Мы попросили Sphinx предоставить нам идентификаторы документов, соответствующие нашим параметрам поиска, а затем мы использовали эти идентификаторы для запуска запроса к базе данных. В случае, если данные, которые мы хотим вернуть, включены в индекс (например, атрибут DOJ в нашем случае), мы можем пропустить часть базы данных, поэтому выбирайте, какой объем информации (атрибутов) вы хотите включить при индексировании данных sql.

Ну вот и все … пора прощаться. Позаботьтесь о своем здоровье и не забудьте проголосовать, это обязательно ?

— Munish Gogna