ublog

налаштування manticore search

programming [45]erlang [41]linux [24]postgresql [12]

налаштуємо manticore search/sphinx search в debian
для завантаження даних для індексування з postgresql


спочатку створимо таблицю в потсгресі
для наповнення тестовими даними для індексації
CREATE TABLE "test_manticore" (
  "id" serial NOT NULL,
  "category_id" integer,
  "name" varchar(255),
  "text" text,
  "inserted_at" TIMESTAMP NOT NULL DEFAULT LOCALTIMESTAMP(0),
PRIMARY KEY ("id")
);

код функції (erlang, модуль hm)
для генерування тестових даних і наповнення таблиці
test_data_4testtable(0) ->
  io:format("~p~n",["test data ok"]);
test_data_4testtable(N) ->
  Map0 = #{1 => "apple", 2 => "door", 3 => "funny", 4 => "sunny", 5 => "green",
    6 => "yellow", 7 => "snow", 8 => "rain", 9 => "frosty", 10 => "mouse", 11 => <<"яблуко"/utf8>>,
    12 => <<"двері"/utf8>>, 13 => <<"смішний"/utf8>>, 14 => <<"сонячно"/utf8>>, 15 => <<"дощ"/utf8>>,
    16 => <<"мороз"/utf8>>, 17 => <<"мишка"/utf8>>, 18 => <<"зелений"/utf8>>, 19 => <<"жовтий"/utf8>>,
    20 => <<"фіолет"/utf8>>}, % other words
  R01 = rand:uniform(20), % count of repeat for text
  R02 = rand:uniform(3), %for name -- 1 -- add before, 2 -- add after, 3 -- no add
  R03 = rand:uniform(2), %for text -- 1 -- add before, 2 -- add after
  V01 = maps:get(R01,Map0), % value for repeat
  
  Map1 = #{1 => <<"штани"/utf8>>, 2 => "abcd", 3 => <<"шоколад"/utf8>>, 4 => <<"рукавички"/utf8>>, 5 => <<"бензин"/utf8>>,
    6 => <<"торт"/utf8>>}, % map with values -- words for search
  R1 = rand:uniform(6), %for name  -- rand from 1 to 6 - key
  R2 = rand:uniform(6), %for text -- rand from 1 to 6 - key
  V1 = maps:get(R1,Map1), % get value by rand key -- for name
  V2 = maps:get(R2,Map1), % for text
  
  Name = case R02 of
    1 ->
      [ V01, " ", V1 ];
    2 ->
      [ V1, " ", V01 ];
    %3 ->
    _ ->
      V1
  end,
  Name2 = unicode:characters_to_binary(Name,utf8),
  
  Text_Add = string:copies([V01, " "], R01),
  Text = case R03 of
    1 ->
      [ Text_Add, V2 ];
    %2 ->
    _ ->
      [ V2, " ", Text_Add ]
  end,
  Text2 = unicode:characters_to_binary(Text,utf8),
  
  Cat_Id = rand:uniform(100),
  
  Id = pg:returning("INSERT INTO test_manticore (category_id, name, text) VALUES($1, $2, $3) RETURNING id", [Cat_Id, Name2, Text2]),
  io:format("data: ~p~n",[Id]),
  ?MODULE:test_data_4testtable(N-1).


після генерування даних, і перед індексацією, нам потрібно створити індекси
нюанси -- rt індекс дозволяє видаляти та змінювати рядки, та не дозволяє імпортувати дані з бази,
plain індекс дозволяє імпортувати з бази, не дозволяє змінювати дані
створимо два індекси -- rt та plain, спочатку імпортуємо дані в другий, потім "переключимо" його на перший відповідно
(для тестів, на проді звичайно додаватимемо дані одразу в rt по мірі потреби)

редагуємо налаштування - прописуємо індекси та доступ до постгреса,
також запит до бази, який дістає потрібні для індексації рядки
$ sudo vim /etc/sphinxsearch/sphinx.conf

source test777
{
  type = pgsql
  sql_host = localhost
  sql_user = dbuser
  sql_pass = dbuser_pass
  sql_db = db_name
  sql_port = 6432
  
  sql_query = SELECT id, category_id, name, text, EXTRACT(EPOCH FROM inserted_at) AS inserted_at FROM test_manticore
  
  sql_attr_uint = category_id
  sql_attr_timestamp = inserted_at
  
  sql_ranged_throttle = 0
}

index test777
{
  source = test777
  type = plain
  path = /var/lib/manticore/data/test777
  
  rt_field = name
  rt_field = text
  
  rt_attr_uint = category_id
  rt_attr_timestamp = inserted_at
}

index test888
{
  type = rt
  path = /var/lib/manticore/data/test888
  
  rt_field = name
  rt_field = text
  
  rt_attr_uint = category_id
  rt_attr_timestamp = inserted_at
}

searchd
{
...
listen = 127.0.0.1:9312
listen = 127.0.0.1:9306:mysql41
...
}

імпортуємо дані, індексуємо
$ sudo systemctl start manticore
$ sudo -u manticore indexer test777

using config file '/etc/sphinxsearch/sphinx.conf'...
indexing index 'test777'...
collected 2000000 docs, 282.2 MB
sorted 29.7 Mhits, 100.0% done
total 2000000 docs, 282233779 bytes
total 20.082 sec, 14053709 bytes/sec, 99589.14 docs/sec
total 13 reads, 0.049 sec, 7133.4 kb/call avg, 3.8 msec/call avg
total 143 writes, 0.202 sec, 1317.9 kb/call avg, 1.4 msec/call avg

далі "переключаємо" індекс
$ mysql -h0 -P9306

MySQL [(none)]> ATTACH INDEX test777 TO RTINDEX test888;
Query OK, 0 rows affected (0.01 sec)

тестова вибірка
MySQL [(none)]> SELECT *, WEIGHT() FROM test888 WHERE MATCH('abcd') AND category_id = 10  ORDER BY WEIGHT() DESC, id ASC LIMIT 0,10;
+-------+-------------+-------------+----------+
| id    | category_id | inserted_at | weight() |
+-------+-------------+-------------+----------+
|  1331 |          10 |  1544473041 |    2517 |
|  3981 |          10 |  1544473047 |    2517 |
|  4763 |          10 |  1544473049 |    2517 |
|  8972 |          10 |  1544473060 |    2517 |
| 10299 |          10 |  1544473062 |    2517 |
| 15071 |          10 |  1544473209 |    2517 |
| 24763 |          10 |  1544473232 |    2517 |
| 26439 |          10 |  1544473236 |    2517 |
| 37707 |          10 |  1544473264 |    2517 |
| 42426 |          10 |  1544473275 |    2517 |
+-------+-------------+-------------+----------+
10 rows in set (0.08 sec)

далі у нас є варіанти на вибір --
1 -- з додатка бігаємо до мантикори, з набором id з мантикори бігаємо до посгреса за даними для виводу
2 -- встановимо розширення для постгреса, яке буде бігати до мантикори, ми ж пишемо лише запити до постгреса

у випадку вибору варіанту 2 продовжимо
(на тому сервері стояв постгрес 9.5, було лінь оновляти, тому як є :) )
$ mkdir tmp
$ cd tmp

~/tmp$ sudo wget https://github.com/andy128k/pg-sphinx/archive/master.zip

$ sudo apt-get install unzip
//$ unzip master.zip -d test
$ unzip master.zip
cd pg-sphinx-master

sudo psql -h localhost dbname user
SELECT version();

PostgreSQL 9.5

sudo apt search postgresql-server-dev-
sudo apt-get install postgresql-server-dev-9.5
sudo apt-get install checkinstall

$ sudo make
$ sudo make install

$ sudo -u postgres psql
\c db
CREATE EXTENSION sphinx;
\q

далі ми можемо писати запити до постгреса з використанням встановленого розширення
db=> SELECT sphinx_select( 'testrt', '"list of business laptops"/3', '', '', 0, 10, '');
 sphinx_select 
---------------
 (1,2397)
 (2,2397)
 (3,2375)
 (5,2375)
(4 rows)

db=> SELECT * FROM sphinx_select('test888', 'abcd', 'id > 0', 'id ASC', 0, 10, NULL);
 id | weight 
----+--------
  1 |  1512
 13 |  1512
 15 |  1512
 23 |  1512
 24 |  1512
 31 |  1512
 35 |  1512
 39 |  2517
 42 |  1512
 44 |  1512
(10 rows)

db=> SELECT * FROM sphinx_select('test888', 'abcd', 'id > 1', 'id ASC', 0, 10, NULL);
 id | weight 
----+--------
 13 |  1512
 15 |  1512
 23 |  1512
 24 |  1512
 31 |  1512
 35 |  1512
 39 |  2517
 42 |  1512
 44 |  1512
 45 |  1512
(10 rows)

-- sphinx_select('index', 'search_text', 'where', 'order', offset, limit, options)


-- SELECT *, WEIGHT() FROM test888 WHERE MATCH('abcd') AND category_id = 10  ORDER BY WEIGHT() DESC, id ASC LIMIT 0,10;
db=> SELECT * FROM sphinx_select('test888', 'abcd', 'category_id = 10', 'WEIGHT() DESC, id ASC', 0, 10, NULL);
  id  | weight 
-------+--------
  1331 |  2517
  3981 |  2517
  4763 |  2517
  8972 |  2517
 10299 |  2517
 15071 |  2517
 24763 |  2517
 26439 |  2517
 37707 |  2517
 42426 |  2517
(10 rows)

SELECT test_manticore.*, ss.weight
  FROM test_manticore
  INNER JOIN sphinx_select(
  'test888',      /* індекс */
  'abcd',  /* запис */
  'category_id = 10',  /* додаткові умови */
  'WEIGHT() DESC, id ASC',  /* порядок сортування */
  0,                  /* offset */
  3,                  /* limit */
  NULL)              /* options */
  AS ss ON ss.id = test_manticore.id;

-- SELECT test_manticore.*, ss.weight FROM test_manticore INNER JOIN sphinx_select('test888','abcd','category_id = 10','WEIGHT() DESC, id ASC',0,3,NULL) AS ss ON ss.id = test_manticore.id;

  id  | category_id |    name    |                                text                                |    inserted_at    | weight 
------+-------------+-------------+----------------------------------------------------------------------+---------------------+--------
 1331 |          10 | sunny abcd  | abcd sunny sunny sunny sunny                                        | 2018-12-10 20:17:21 |  2517
 3981 |          10 | abcd frosty | abcd frosty frosty frosty frosty frosty frosty frosty frosty frosty  | 2018-12-10 20:17:27 |  2517
 4763 |          10 | abcd        | abcd yellow yellow yellow yellow yellow yellow                      | 2018-12-10 20:17:29 |  2517



посилання по темі
https://manticoresearch.com/
https://manticoresearch.com/2018/04/05/basics-of-manticore-indexes/#real-time-indexes
https://docs.manticoresearch.com/latest/html/sphinxql_reference/attach_index_syntax.html
https://docs.manticoresearch.com/latest/html/command_line_tools_reference/indexer_command_reference.html
https://docs.manticoresearch.com/latest/html/sphinxql_reference/select_syntax.html#limit
https://anadea.info/ru/blog/postgresql-and-sphinx-search-seamless-integration
https://github.com/andy128k/pg-sphinx


поки це все :)