В нашем бэк-офисе мы будем использовать Cloudsearch для поисковой части вместо некоторого запроса Mysql.
Проблема в том, что у меня возникли проблемы с получением того же результата с Cloudsearch, и мне нужна помощь, если это возможно …
Например, если поиск пользователя «Александр Колл«:
С Mysql : один результат для события с именем «Александр & блаблабла ВызовXXX»
Для получения дополнительной информации, запрос Mysql использовать некоторые ... WHERE CONCAT(FIELD1, " ", FIELD2, " ", FIELD 3) LIKE '%alexandre%' AND CONCAT(FIELD1, " ", FIELD2, " ", FIELD 3) LIKE '%call%'
для моего примера.
С Cloudsearch : 280 результатов, с событием, содержащим «Александр«ИЛИ событие, которое содержит»вызов«или слово с суффиксом»вызов + что-то»
Вот как я использую Cloudsearch с AWS SDK for PHP
:
1 / Я подключаюсь к своему поисковому домену:
$client = CloudSearchDomainClient::factory(array(
'endpoint' => 'https://XXXXXXXX.eu-west-1.cloudsearch.amazonaws.com',
'validation' => false,
'version' => 'latest',
'credentials' => [
'key' => _S3_API_KEY_,
'secret' => _S3_API_SECRET_,
],
'region' => 'eu-west-1',
));
2 / Мои исследования:
$search_result['event'] = $client->search(
array(
// This is what user search, in my example $query = "Alexandre Call"'query' => $query,
'queryOptions' => '{
"defaultOperator" : "or",
"fields":["description","nomevent^3", "idftpevent^2"]
}',
'queryParser' => 'simple',
'size' => 500,
'start' => 0
)
);
С этим я получаю 280 результатов, как я уже сказал …Любая идея, как я могу получить аналогичный результат, который я имею с MySQL?
Редактировать :
Я думаю, что хотел бы найти что-то вроде этого, но я не знаю, как:
(and
(or description='alexandre' nomevent='alexandre' idftpevent='alexandre')
(or description='call' nomevent='call' idftpevent='call')
)
Но невозможно заставить это работать … идея должна состоять в том, чтобы иметь alexandre
по крайней мере, один раз в 3 полях, которые я ищу, и то же самое для call
(для термина как call, call, callXXX …), есть идеи?
Редактировать 2 :
Я попробовал решение для моего примера:
$event_query = 'alexander* call*';
$search_result['event'] = $client->search(
array(
'query' => $event_query,
'queryOptions' => '{
"defaultOperator": "and",
"fields":["nomevent^3","idftpevent^2", "description"]
}',
'queryParser' => 'simple',
'size' => 500,
'start' => 0
)
);
Но я не получил результата … Я сделал что-то не так?
У меня есть проблемы, чтобы понять, что "defaultOperator": "and",
используется для? Значит я ищу alexandre*
А ТАКЖЕ call*
или это означает, что я ищу alexandre*
а также call*
в 3 полях я упоминаю?
Как я показал ранее, я хотел бы найти alexandre*
в одном из 3 полей я упоминаю И call*
по крайней мере, в одном из 3 полей, которые я упоминаю
Я думаю, что хотел бы найти что-то вроде этого, но я не знаю, как:
(and (or description='alexandre' nomevent='alexandre' idftpevent='alexandre') (or description='call' nomevent='call' idftpevent='call') )
Это довольно близко, но я думаю, что вы можете упростить это много используя встроенные операторы из simple
анализатор запросов. С этим парсером префиксные запросы используют *
в конце слова или фразы, чтобы указать, что вы ищете совпадения, которые начинаются с предыдущих символов. Таким образом, ваш запрос должен выглядеть следующим образом:
/* Only treat the last word as a prefix */
alexandre call*
/* Treat each word as a prefix */
alexandre* call*
Теперь, чтобы соответствовать and
логика составного запроса, который вы пробовали, вам просто нужно изменить defaultOperator
в and
(или удалите эту опцию, потому что and
по умолчанию).
Надеюсь, это поможет!
Я принимаю другое решение, но я все равно добавлю то, что я действительно сделал, если люди захотят увидеть, как оно выглядит AWS SDK for PHP
:
1 / Я получаю, что пользователь ищет и «чистит» поиск:
$_REQUEST['search'] = preg_replace(
array('/\+/', '/-/', '/~/', '/>/', '/</', '/"/', '/\'/', '/\)/', '/\(/'),
"",
$_REQUEST['search']
);
2 / Затем я разбираю поиск, чтобы получить каждое слово одно за другим:
$word_list = explode(" ", trim($_REQUEST['search']));
3 / Теперь я могу построить свой запрос:
// I start my query
$event_query = "(and ";
// Now for each word, I add my condition :
// - I want each searched word in at least one of my 3 fields (nomevent, idftpevent and description)
// - I want the exact word or just a prefix
foreach ($word_list as $word) {
$event_query .= "(or
(prefix field=description '".$word."')
(prefix field=nomevent '".$word."')
(prefix field=idftpevent '".$word."')
(term field=description '".$word."')
(term field=nomevent '".$word."')
(term field=idftpevent '".$word."')
)";
}
// I close my query
$event_query .= ")";
4 / Теперь я просто должен использовать AWS SDK for PHP
чтобы получить мой результат:
$search_result['event'] = $client->search(
array(
'query' => $event_query,
'queryParser' => 'structured',
'size' => 500,
'start' => 0
)
);
$search_result['event'] = $search_result['event']->toArray();
И результат в $search_result['event']['hits']['hit']
есть лучший способ получить те hit
но так я добиваюсь того, чего хотел!