검색엔진/Sphinx

스핑크스란 ?

이건욱 2020. 4. 3. 15:01

프로젝트를 진행을 하다 보면 , 검색 기능이 필요할 때가 있습니다.

 

일반적으로 SQL에서 검색을 한다면 LIKE로 할수 있습니다. 데이터가 많지 않을 경우에는 충분 하지만 많을 경우에는 FullTable Scan이기 때문에 성능상 좋지 않습니다.

 

이런 검색을 위해서 다양한 DB에서 Full Text Search을 지원 합니다. 

하지만 상황에 따라서는 Like문과 병행해서 사용을 하게 되고 그러면서 검색 엔진에 대한 고민을 시작하게 되는거 같습니다.

 

따라서 스핑크스 특징 :)

  • Real-Time full-text indexes
  • SQL database indexing
  • Non-SQL storage indexing
  • Easy application integration
  • Advanced full-text searching syntax
  • Rich database-like querying features
  • High indexing and searching performance
  • Proven scalability up to billions of documents, terabytes of data, and thousands of queries per second.

 

1) 설치

sudo apt-get install sphinxsearch

 

2) 환경 설정

--
-- Database: `sphinx_demo`
--
CREATE DATABASE IF NOT EXISTS `sphinx_demo` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
USE `sphinx_demo`;
-- --------------------------------------------------------
--
-- Table structure for table `products`
--
CREATE TABLE `products` (
  `id` int(11) NOT NULL,
  `design_no` varchar(32) NOT NULL,
  `album_id` int(10) NOT NULL,
  `catalogno` text NOT NULL,
  `brand` text NOT NULL,
  `product` text NOT NULL,
  `fabric` text NOT NULL,
  `stock` text NOT NULL,
  `total_products` varchar(32) NOT NULL,
  `Image` text NOT NULL,
  `subcategory` varchar(50) NOT NULL,
  `category_id` varchar(32) NOT NULL,
  `wholesale_price` varchar(100) NOT NULL,
  `weight` varchar(10) NOT NULL,
  `fcolor` text NOT NULL,
  `fwork` text NOT NULL,
  `ffabric` text NOT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
--
-- Dumping data for table `products`
--
INSERT INTO `products` (`id`, `design_no`, `album_id`, `catalogno`, `brand`, `product`, `fabric`, `stock`, `total_products`, `Image`, `subcategory`, `category_id`, `wholesale_price`, `weight`, `fcolor`, `fwork`, `ffabric`, `created`) VALUES
(1, '182A', 1, '1857', 'Jashan', 'Jashan R812 New Colors red', 'Top - Georgette , Inner - Santoon , Dupatta - Nazmin', 'Available', '10', '1857-182A.JPG', 'Suit', '1', '1750', '1', '', '', '', '2017-09-02 05:03:15'),
(2, '182B', 1, '1857', 'Jashan', 'Jashan R812 New Colors', 'Top - Georgette , Inner - Santoon , Dupatta - Nazmin', 'Available', '10', '1857-182B.JPG', 'Suit', '1', '1750', '1', '', '', '', '2017-09-02 05:03:15'),
(3, '182C', 1, '1857', 'Jashan', 'Jashan R812 New Colors blue', 'Top - Georgette , Inner - Santoon , Dupatta - Nazmin', 'Available', '10', '1857-182C.JPG', 'Suit', '1', '1750', '1', '', '', '', '2017-09-02 05:03:15'),
(4, '182D', 1, '1857', 'Jashan', 'Jashan R812 New Colors', 'Top - Georgette , Inner - Santoon , Dupatta - Nazmin', 'Available', '10', '1857-182D.JPG', 'Suit', '1', '1750', '1', '', '', '', '2017-09-02 05:03:15'),
(5, '23001', 2, '1002', 'Arihant Designer', 'Hamom Vol 10', 'Faux Geogette Lehenga - net , Inner - Santon', 'Ready To Ship', '10', '1856-23001.JPG', 'Suit', '1', '1635', '1', '', '', '', '2017-09-02 05:03:15'),
(6, '23002', 2, '1002', 'Arihant Designer', 'Hamom Vol 10', 'Faux Geogette Lehenga - net , Inner - Santon', 'Ready To Ship', '10', '1856-23002.JPG', 'Suit', '1', '1640', '1', '', '', '', '2017-09-02 05:03:15'),
(7, '23003', 2, '1002', 'Arihant Designer', 'Hamom Vol 10', 'Faux Geogette Lehenga - net , Inner - Santon', 'Ready To Ship', '10', '1856-23003.JPG', 'Suit', '1', '1575', '1', '', '', '', '2017-09-02 05:03:15'),
(8, '23004', 2, '1002', 'Arihant Designer', 'Hamom Vol 10', 'Faux Geogette Lehenga - net , Inner - Santon', 'Ready To Ship', '10', '1856-23004.JPG', 'Suit', '1', '1545', '1', '', '', '', '2017-09-02 05:03:15'),
(9, '23005', 2, '1002', 'Arihant Designer', 'Hamom Vol 10', 'Faux Geogette Lehenga - net , Inner - Santon', 'Ready To Ship', '10', '1856-23005.JPG', 'Suit', '1', '1595', '1', '', '', '', '2017-09-02 05:03:15'),
(10, '23006', 2, '1002', 'Arihant Designer', 'Hamom Vol 10', 'Faux Geogette Lehenga - net , Inner - Santon', 'Ready To Ship', '10', '1856-23006.JPG', 'Suit', '1', '1670', '1', '', '', '', '2017-09-02 05:03:15'),
(11, '1121', 1, '1874', 'Aardhngini', 'Ardhagini Saree Shashi Series 1121 to 113', 'Fancy', 'Available', '10', '1856-23006.JPG', 'gown', '1', '1695', '1', 'Red', 'Stone', 'Net', '2017-09-02 05:04:04');
--
-- Indexes for dumped tables
--
--
-- Indexes for table `products`
--
ALTER TABLE `products`
  ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `products`
--
ALTER TABLE `products`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=12;

 

3) sphinx.conf 설정 변경

 

sudo vim /etc/sphinxsearch/sphinx.conf
source src1 
{
  type          = mysql
  sql_host      = localhost 
  sql_user      = root
  sql_pass      = Password
  sql_db        = sphinx_demo
  sql_port      = 3306
  sql_query_pre = SET NAMES UTF8

sql_query     = \
  SELECT id, design_no, album_id, product, fabric, stock, UNIX_TIMESTAMP(created) AS date_added \
  FROM products
  
sql_attr_uint    = id
  sql_field_string = design_no
  sql_field_string = album_id
  sql_field_string = product
  sql_field_string = fabric
  sql_field_string = stock
  sql_attr_timestamp = date_added
}
index test1
{
  source            = src1
  path              = /var/lib/sphinxsearch/data/test1
  docinfo           = extern
  	charset_type	= utf-8
	charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F
	ngram_len = 1
	ngram_chars =  U+4E00..U+9FBB, U+3400..U+4DB5, U+20000..U+2A6D6, U+FA0E, U+FA0F, U+FA11, U+FA13, U+FA14, U+FA1F, U+FA21, U+FA23, U+FA24, U+FA27, U+FA28, U+FA29, U+3105..U+312C, U+31A0..U+31B7, U+3041, U+3043, U+3045, U+3047, U+3049, U+304B, U+304D, U+304F, U+3051, U+3053, U+3055, U+3057, U+3059, U+305B, U+305D, U+305F, U+3061, U+3063, U+3066, U+3068, U+306A..U+306F, U+3072, U+3075, U+3078, U+307B, U+307E..U+3083, U+3085, U+3087, U+3089..U+308E, U+3090..U+3093, U+30A1, U+30A3, U+30A5, U+30A7, U+30A9, U+30AD, U+30AF, U+30B3, U+30B5, U+30BB, U+30BD, U+30BF, U+30C1, U+30C3, U+30C4, U+30C6, U+30CA, U+30CB, U+30CD, U+30CE, U+30DE, U+30DF, U+30E1, U+30E2, U+30E3, U+30E5, U+30E7, U+30EE, U+30F0..U+30F3, U+30F5, U+30F6, U+31F0, U+31F1, U+31F2, U+31F3, U+31F4, U+31F5, U+31F6, U+31F7, U+31F8, U+31F9, U+31FA, U+31FB, U+31FC, U+31FD, U+31FE, U+31FF, U+AC00..U+D7A3, U+1100..U+1159, U+1161..U+11A2, U+11A8..U+11F9, U+A000..U+A48C, U+A492..U+A4C6
}
searchd
{
  listen            = 9306:mysql41
  log               = /var/log/sphinxsearch/searchd.log
  query_log         = /var/log/sphinxsearch/query.log
  read_timeout      = 5
  max_children      = 30
  pid_file          = /var/run/sphinxsearch/searchd.pid
  seamless_rotate   = 1
  preopen_indexes   = 1
  unlink_old        = 1
  binlog_path       = /var/lib/sphinxsearch/data
}

설명 :)

source 뒤에 위치한 내용은 별칭 입니다.

 

sql_pass :)

DB PASSWORD에 특수 문자가 포함되어 있으면 escape(\) 처리를 해야합니다. 

 

sql_query_pre :)

유니코드를 제대로 출력하기 위해서 사용

 

sql_query :)

products 라는 테이블에서 index을 어떻게 구성할건지에 대한 정보 ( 첫번째 컬럼은 반드시 unique 한 primary key)
attr은 검색을 제외한 정렬을 할 때 사용 ( sql_field_string 이런 타입 정보는 링크 참조 )

 

index :)

index 뒤에 이름은 나중에 database에서 검색을 할 때 사용이 됩니다. ex) SELECT * FROM test1;

path는 저장될 위치입니다.

 

charset_type , charset_table , ngram_len , ngram_chars   :)

한글 설정을 위한 세팅 입니다.

 

searchd :)

sphinx 서비스를 실행을 시킬 때에 대한 정보입니다.

 

 

전체 인덱싱 :)

sudo indexer --all --rotate

rotate는 기존에 이미 searched 프로세스를 실행했다면 붙혀야 합니다.

 

RT (Real Time) 가 아닌 이상 주기적으로 Cron같은 걸 써서 update를 진행해야 합니다.

 

부분 인덱싱 :)

indexer 인덱스 명

 

서비스 실행 :)

$ sudo searchd -c ./sphinx.conf 

 

서비스 실행 여부 확인 :)

$ ps aux | grep searchd

 

서비스 접속 :)

mysql -h0 -P9306

 

간단한 예시 :)