Необходимо написать php класс FoodSearch (в виде composer package) реализующий функционал различных видов поиска по продуктам/рецептам.

Разработку выполнять в git репозитарии https://github.com/YadrovSergey/FoodSearch

Также в этот репозитарий положить конфиг настроек sphinx (его необходимо обсудить совместно).

Используем: Sphinx 2.1, SphinxQL, RT index.

Разработку и тестирование производить на виртуальной машине «1C-Битрикс: Виртуальная машина 5.1» ( http://www.1c-bitrix.ru/download/vmbitrix.php )!

На ней установлен php, Sphinx. Т.е. все, что нужно для реализации данной задачи. Скачать ее можно здесь http://repos.1c-bitrix.ru/vm/VMBitrix5.1.2-vmware.zip

Поиск будет осуществляться по двум базам продуктов:

1. Общая база продуктов и рецептов. id_source = 0

2. База продуктов и рецептов пользователей. id_source = 1

Тестовые данные будут предоставлены. Общая база порядка 7000 наименований, база пользователей – 300 000 (она постояно растет).

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

Функции заполнения Sphinx данными.

->addFood($nIdSource, $arFields) – добавляет в заданную базу продукт. Если продукт уже существует в базе, то будет обновлен.

$nIdSource – в какую базу будет добавляться продукт. 0 – Общая база, 1 – база пользователей.

$arFields – ассоциативный массив полей для добавления в поиск.

Пример полей можно увидеть в файлах с тестовыми данными.

->deleteFood($nIdSource, $nId) – удаляет продукт из соответствующей базы.

->loadFromFile($nIdSource, $sPathToFile) – заполняет Sphinx тестовыми данными из предоставленных файлов. Будет использоваться в основном для тестирование поиска.

Общие замечания

Все функции должны быть chainable.

Вначале вызываем функции установки фильтра, сортировок, группировки, а затем функции поиска.

Например, $foodSearch->filterSource(0)->filterTypeOfFo od(0)->limit(50)->search("яблоко")

Формат результата поиска – ассоциативный массив.

array(

array(* все поля данных),

...

);

Функции установки фильтра.

->filterAccount($nIdAccount) – устанавливает фильтр по полю "id_account"

->limit($nRowCount, $nOffset = 0) – устанавливаем лимит выборки.

->filterSource($nIdSource) – устанавливает индекс, по которому будет осуществляться поиск. 0 – Общая база, 1 – база пользователей. Если не установлен, то поиск будет идти по общей базе и базе пользователей. Данная функция влияет на From.

->filterPublished($nIsPubleshed) – фильтр по полю is_published.

->filterGroupId($GroupId) – фильтр по полю group_id. Может быть задан в виде массива.

->filterGroupName($GroupName) – фильтр по полю group. Может быть задан в виде массива.

->filterNutrients($arNutrients) – фильтр по полю nutrients. Где nutrients содержит JSON данные.

$arNutrients- это ассоциативный массив, который содержит ids nutrients для фильтрации.

Например:

array(

"1"=> array("from"=>100)

"4"=> array("to"=>100)

"5"=> array("from"=>1, "to"=>200)

);

В итоге будет фильтр: ingredients.1 > 100 and ingredients.4 filterSourceOfComposition($nSourceOfCompos ition) – фильтр по полю source_of_composition. Может быть задан в виде массива.

->filterTypeOfFood($nTypeOfFood) – фильтр по полю type_of_food.

Функции группировки.

->groupByGroupName() – группировка по полю group.

->groupByGroupId() – группировка по полю group_id.

Вопрос. Можно ли дополнительно сортировать группы в результате?

Функции сортировки.

->sortBy($sColName, $SortType="DESC") – устанавливаем сортировку по полю. Может быть вызвана несколько раз, в этом случае будет сортировка будет по нескольким полям.

Функции поиска.

->search($sQuery = "") – поиск продуктов по строке.

$sQuery – строка поиска. Может быть вида "Яблоко", "Яблоко салат", "Ябл".

Поиск осуществляется по полю "name".

Поиск с учетом морфологии. Например, "Яблоко" должно найти "Яблоки".

Может быть задано слово не полностью, а только его начало. Минимально 3 символа. Например, "ябл", "карто"

Чем ближе искомая фраза к началу, тем выше результат в поиске. Например, есть "Яблоки салат" и "салат из яблок". Выше должна быть первая строка.

На результат поиска не должно влиять количество вхождений искомой фразы в поле "name".

Если $sQuery задано в виде пустой строки, то значит мы хотим найти все продукты удовлетворяющие заданным фильтрам.

Например, $foodSearch->filterSource(0)->filterTypeOfFo od(0)->limit(50)->search("яблоко") ,

$foodSearch->filterNutrients(array("1" => array("from"=>100)))->limit(50)-> search()

->searchInIngredients($arIngredients) – поиск рецептов по ингредиентам. Т.е. ищем рецепты, в составе которых есть заданные ингредиенты

$arIngredients – массив ингредиентов, который должен содержать рецепт. Например, array("яблоки", "огурец")

Поиск осуществляется по полю "ingredients".

Поиск с учетом морфологии.

Например, $foodSearch->filterTypeOfFood(1)->sortBy(" rating","DESC")->limit(50)-> filterPublished(1)->searchInIngredients(array ("яблоки", "огурец"))

10 лет назад
Belyi92
Игорь 
33 года
12 лет в сервисе
Был
10 лет назад
4 отзыва

Заявки фрилансеров

Нет заявок фрилансеров