Pull to refresh

Comments 33

Хорошая, наверно, работа получилась. Молодцы.
К нам когда-то обратился клиент, у которого подобным образом сливались прайсы поставщиков и возникла проблема, что в авторежиме какая-то группа NVMe накопителей идентифицировалась как SATA, соответственно в анализ и прайс шли цены на порядок ниже. Это вызвало довольно много неприятных моментов в общении с клиентами.
Изучив проблему, перестроили систему таким образом:
1) уболтали всех поставщиков предоставлять в прайсе свои артикулы, артикулы производителя и наименование товара в отдельных колонках (в цифрах — порядка 50 поставщиков, ассортимент 250к уникальных позиций, ежедневная загрузка порядка 2х миллионов строк);
2) создали внутренний «эталонный» справочник наименований товаров, каждому товары присвоили свой уникальный артикул;
3) процедура автоматической линковки товаров поставщиков к эталонному справочнику осталась преимущественно старой, но добавили возможность ручной перелинковки в случае ошибки, слинкованные товары (автоматически или вручную) в автолинковку уже не попадали;
4) во все товарные документы, с момента определения поставщика и партии, стали подставлять наименование и артикул поставщика, чтобы менеджер/кладовщик мог вычитать и сообщить, если автолинковка дала сбой и товар, который заказал клиент это не тот, который предлагает поставщик.
Компания осталась довольна, хаос стал подконтрольным, залёты с ценами прекратились.
Возможно, это будет следующим шагом и в вашей системе.
Хорошо когда поставщики готовы что-то менять. Хотел уточнить как с таким справляетесь, пример «согласовали прайс поставщика» уточнили 100% вот железно ничего менять не будут. Через 3 дня либо добавят колонку в xls, либо поменяют её название, либо вообще другой файл пришлют. Потом оказывается что они его руками формируют. Дошло до того что перед заливкой данных из прайса идет сравнение с прошлым прайсом на предмет «не поменялся ли формат» и если поменялся — уходит уведомление руководителю торгового направления.
Мы делаем так: у поставщиков есть конфигурируемое время устаревания, а поставщика мы автоматически узнаем по формату файла (названия колонок, вкладок, возможно, контактная информация в файле). Если колонки добавились, поменялись местами и так далее — то все ок, мы его узнаём и продолжаем обрабатывать. Если совсем другой файл — мы его не обработаем, соответственно, цены устареют, и мы покажем об этом предупреждение на главной странице. Пойти и исправить настройки под новый формат занимает две-три минуты, поэтому исправляем сами и с поставщиком даже не связываемся (если это не системно происходит).

При работе с 400 поставщиками менять настройки приходится один-два раза в неделю.
Phoenix-lib,
Было несколько поставщиков, у которых ИТ на аутсорсе, и им пришлось помочь с формированием выгрузки прайса из учетной системы.
Но по большому счету они все уже работали на автомате, руками в эксель никто не лазил, как их учетная система формировала файл, так его и высылали. Учетки разные (1с 7/8, SAP, Axapta, кастомные CRM, в т.ч. на ASP, PHP), но эксель выгружали исправно.
Для тех, кто пытался отказаться менять формат файла, у нас был бронебойный аргумент — «Компания не будет вручную разносить ваши цены. Если вы не сможете предоставить выгрузку в приемлемом виде, ваши товары не будут в системе, и компания не сможет их продавать фактически.» Технари, они понятливые. Две колонки в файле делаются за пару часов (с тестами и выкладкой в прод), а при отказе мы пошли бы к их начальству, что ничем хорошим для них не закончилось бы.
Тут надо понимать, что наш заказчик — клиент своих поставщиков, а значит, по рыночным правилам, всегда прав ) Этим и воспользовались.
Дошло до того что перед заливкой данных из прайса идет сравнение с прошлым прайсом на предмет «не поменялся ли формат»
250 тыс товаров, 2 млн строк — в среднем по 8 предложений на товар в нашем случае. Поэтому, если один поставщик не будет загружен из-за неверного формата, или часть строк его будет пропущена, на бизнес-логику нашего заказчика это не повлияло бы, товар не уникальный, есть у конкурентов, пойдет от другого поставщика. Сам поставщик понимает, что не в его интересах менять форматы.
Сама система при загрузке отображает статистику — сколько строк в файле, сколько загружено, сколько из них слинковано, сколько ошибочных строк. Загрузку контролирует оператор, так что на административном уровне может обнаружить косяк с форматом — вылезет большое число ошибок и таблица загружаемых товаров будет пустой после зачитки файла.
Загрузка прямо из почты была отключена, т.к. нужен был контроль за ценообразованием. Т.е. сначала грузятся все прайсы поставщиков, затем рассчитывается и утверждается прейскурант на текущий день для клиентов (прейскурантов несколько, но не суть), после чего клиентам делается автоматическая рассылка сегодняшних цен. И до конца дня работа ведется по этим расчетам. Утром следующего дня цены рассчитываются по-новой.

Вообще, мне сложно представить, что поставщик отказывается менять формат выгрузки прайса или меняет его слишком часто. В его интересах, чтобы его товар продавался быстро и удобно.
Лет 15 назад, когда обмен файлами остатков был еще не у всех и не всегда, были случаи, когда в прайсах могло быть разное количество колонок (например, для разных товарных групп или разных форм оплаты — с НДС/без НДС и колонки). Тогда проще всего было определять номер колонки по заголовку столбца — «Артикул», «Наименование», «Цена», «Остаток». Тоже неплохо работал алгоритм.
До внедрения этой проверки часто могли возникать ситуации когда колонка остатков становились на место цен, а цены на место остатков
У нас всегда перед загрузкой проверяется формат файла и наличие ожидаемых данных в ожидаемых местах. Если, например, в какой-то строке нет артикула — вся строка уходит в отбраковку, результат преобразования в число количества или цены равен или меньше нуля — брак. Разве что наименование не валидировали. Мало ли поставщик просто коды пришлёт, чтобы можно было обновить данные без загрузки новых товаров.
Я вот подумал — 6 человек на зарплате занимаются сопоставлением выгрузки. А может быть найти несколько самых неаккуратных поставщиков и слить их/постаивть ультиматум. Просто жесть же сколько им на зарплату уходит (если в белую).
6 человек на зарплате занимаются сопоставлением выгрузки
Жестко, бессмысленно и беспощадно! )))

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


Уволить — не вариант, у нас план активно расти и, наконец, дело сдвинулось с точки.

А Вы найденные характеристики Яндексу в YML выгружаете?
Да. Но эта часть пока работает на старой инфраструктуре и к ней есть вопросы, в первую очередь по прозрачности процесса.

В свое время делал специальную программу для схожих задач — http://pricematcher.ru. Она даже неплохо продавалась. Потом из-за нехватки времени забросил развитие. Сейчас пет-проджектом потихоньку некий аналог делаю, но с хранением данных в облаке (основное неудобство, с которым сталкивались пользователи pricematcher, было то, что приходилось заморачиваться с установкой и настройкой mssql server).
Ну и есть несколько других готовых программ у моих "конкурентов", которые упрощают процесс сопоставлений прайсов. Поищите, если не искали, а то немного похоже на изобретение велосипеда.

Изначально у нас было платное решение для 1с. Работало плохо, и с идеей перейти на другую систему мы работали два года. Искали, пробовали разные системы. Одну попробовали внедрить, но не пошло. Своё начали делать практически от безысходности.


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

А какие системы ещё всё-таки пробовали? Я отрыл сейчас свои записи. Elbuz E-Trade, как мне казалось, имели наиболее обширные возможности. И ещё штук 20 их там.
Просто из ваших описаний я не увидел никаких особо нестандартных задач, вроде бы все то же самое, что и всем владельцам магазинов обычно надо. Странно, что ничего не подошло

Да, у них самые обширные возможности и их мы рассматривали. У них на сайте есть калькулятор, если количество записей ( каталог, поставщики, конкуренты) выставить в 500 000, больше калькулятор не даёт, то получается больше 1500$ в месяц. А у нас записей больше пяти миллионов, если все считать. Даже на специальных условиях и если поторговаться — много получается. (Мы не торговались, если что)


Или, например, такое в тарифном плане (в другом сервисе) «Ротация: 5 SKU в рабочий день (обрабатываются по 5 SKU в день в порядке добавления)». Это план за 150 долларов. А нам надо минимум в сто раз больше.


Не всех пробовали лично, где-то получалось договориться с партнерами день поработать у них и посмотреть, как все происходит.


Делать антирекламу кому-то я не хочу, поэтому перечислять всех не буду.

Вот что только люди не делают, лишь бы не внедрять MDM
Очень здорово, когда есть несколько алгоритмов для 400 поставщиков! Представляю себе ситуацию, когда каждый поставщик будет предоставлять свои API и для магазина потребуется много реализаций. :)

Как вы считаете, правда ли то, что если на СНГ рынок ворвётся Amazon или EBAY, то можно сворачивать активность своего интернет магазина?
Думаю, да, если придет амазон или алибаба — все сильно изменится. Ебей скорее останется незамеченным. Но в любом случае рынок будет стремиться к укрупнению, останется только несколько крупных игроков. Это не произойдет в один момент. Просто у магазинов в том виде, в котором они есть сейчас, дела пойдут немного хуже. Через год закроется 20%. Еще через год — еще 20%. И увидеть переломный момент и начать менять концепцию бизнеса смогут не все, большинство будет занято текущими проблемами.

Но в то же время, я думаю, у интернет-магазинов есть шанс адаптироваться. Уйти в узкие ниши во-первых. Амазон все же про массовость. Принять амазон как площадку и работать по его правилам, во-вторых. Стать сервисным провайдером для того же амазона, в-третьих. Построить инфраструктуру с нуля на всей террирории России пока никому не удавалось, и вряд ли Амазон в это станет вкладываться.
Как вы считаете, правда ли то, что если на СНГ рынок ворвётся Amazon или EBAY, то можно сворачивать активность своего интернет магазина?
Амазон и Ебей — это разные системы. Общего у них только агрегатор интернет-магазинов (у нас есть Яндекс.Маркет). Амазон.Пэй конкурирует с Пейпал (аналог Яндекс.Деньги). Амазон прайм, фулфилмент и стор не имеют аналогов в Ебей и Яндексе.
Таким образом, что-то измениться может, только если Амазон захочет открыть свой магазин и автоматом потянет фулфилмент и прайм услуги.
Вероятность такого события крайне мала, т.к. для открытия своего магазина придется сертифицировать кучу товаров, либо использовать локальных поставщиков, которых используют все другие интернет-магазины. В любом случае для Амазона это будет мясорубка, на которой можно построить тотализатор.

С учетом того, что Амазон работает жестко в рамках инструкций, разработка их под российский рынок займёт не один год. И даже если инструкции будут успешно разработаны, у интернет-магазинов будет достаточно времени, чтобы адаптироваться — сменить ассортимент или лечь под Амазон заблаговременно.
если на СНГ рынок ворвётся Amazon или EBAY


ebay давно пришёл, уже несколько лет назад покупал в русских магазинах разную мелочёвку (речь именно о магазинах, а не о частниках)
1. Расскажите, пожалуйста, каким образом вы создавали начальную базу карточек товаров?
А именно:
— сколько процессов, сколько ip адресов понадобилось и как создавался маршрут для получения необходимой информации :)
— каким образом решали вопрос с водяными знаками на фотографиях

2. Какой тип хостинга предпочли для системы? Рассматривали ли возможность экономии, купив собственное железо, на котором работают массивные части системы например как обработка прайсов и +реплика в облаке на подстраховку в случае отказа локальной машины?
1. По карточкам товаров не могу ответить подробно, это сделано до меня. Но доля ручного труда там большая, настраиваются соответствия, замены и так далее.
Водяные знаки — проблема. В частных случаях помогает опыт олимпиадного программирования и знание принципов обработки изображений.
2. Хетзнер в нашем случае лучше собственного железа. Не надо решать вопросы с охлаждением, питанием и так далее. Машина в облаках с такими характеристиками раз в 10 дороже. Скорее всего, там же и останемся в ближайшее время, возможно, возьмем больше машин по мере роста нагрузки. Архитектура проекта позволяет. Но в настоящем времени на подстраховку у нас только регулярные бекапы.
Поставщикам, которые заказы получают в собственном формате, выгружайте дополнительно каждый раз заказы ещё и в формате, который на Ваш взгляд мог бы быть отраслевым стандартом. Тот же YML. И напоминайте время от времени их начальству, что вот в таком формате всем было бы удобнее, и им в том числе.

Такая вода очень эффективно точит камень. Постепенно, импортилки заказов к себе из такого удобного формата могут сделать очень многие из ваших поставщиков.
Спасибо, попробуем. Дельная идея.
А в процессе работы были ли попытки использовать sphinxsearch?
Нет, конкретно sphinx не пробовали.
Я не работал с sphinx, но elastic или full text search нам не подходят по следующим причинам:
  • Скорость. Я не знаю, как достичь 10 000 сопоставлений в секунду
  • Гибкость. Мы потратили несколько месяцев, придумывая алгоритмы, подбирая оптимальные параметры, тестируя каждое изменение. Я не знаю, как можно настроить, например, больший приоритет у токенов, которые содержат и буквы, и числа.

Со sphinx (или другим универсальным движком) можно получить результат быстрее. Писать что-то свое узкоспециализированное было долго и сложно, но, думаю, это было правильным выбором с учетом нашей цели обрабатывать десятки миллионов товаров в день.
Дальше придумали хэш-функцию, не чувствительную к порядку токенов

А можно немного подробнее раскрыть? Ведь замысел в том, что бы один и тот же товар давал один и тот же хэш, так? Но если в названии товара пропушена часть названия? Разве в припеденном в статье примере все эти название дадут один хэш?
Замысел состоит в том, что есть простые, быстрые и точные способы сопоставить товары. Например, полное совпадение названий. Потом совпадение названий с точностью до перестановок (с оговоркой, что существует единственный вариант). И если сработал один из этих способов, то результат у нас есть, и дальше обрабатывать товар не нужно. Естественно, это работает не всегда, на одних данных ничего не дает, на других дает 10% сопоставлений.

Не все названия из примера дадут одинаковый хэш. Но после алгоритма с хэшированием есть еще другие, которые могут сопоставить эти товары.
Просто перестановка токенов даем же нам комбинаторный взрыв. Или перестановка в одном варианте, допустим в алфавитном? Но это не решает проблему пропущенных токенов в названии т.к. дает другой кэш. Хотя дальше видимо идет сравнение по триграммам или нечто подобное?
А сколько по времени занимает проверка через эту цепочку фильтров проверка? Я на коленке когда-то собирал подобное (используя в том числе морфологический словарь нормализацию слов), но выходило это достаточно долго. Если не ошибаюсь больше секунды.
Мы не генерируем перестановки, хэш-функция, которая не чувствительна к порядку, вполне с этим справляется.
Вариант с пропущенными токенами обрабатывается позже.
Что касается скорости, то на относительно современном ноутбуке (i5-7300HQ) сопоставляется 10 тысяч записей в секунду. С сохранением результатов в базу — 2-5 тысячи в секунду. Обработка 2.5 миллионов цен занимает около 5-10 минут.
10к RPS это в однопоточном режиме, так? Когда все данные для работы находятся в ОЗУ?
А есть ссылки на почитать насчет хэш функции? Я как то привык, что разные строки дают разный хэш. А тут получается без перестановок и учета пропустов две разных строки дают один хэш. Звучит непонятно.
10-20к RPS — это с данными в памяти, да.
А что касается функции, то, не вдаваясь в нюансы, такая будет соответствовать условиям с перестановками. С пропусками — нет, там другой алгоритм, не все сводится к хэшам.

public static int GetHash(string s){
    return GetHash(s.Split(' '));
}

public static int GetHash(IEnumerable<string> tokens)
{
    long hash = 0;
    foreach (var token in tokens.Distinct())
    {
        hash ^= token.GetHashCode();
    }
    return hash;
}
Спасибо, теперь понятно. Я просто изначально немного удивился про хэши. Теперь в целом ясно. Цепочка проверок, каждая вносит в итог какой-то вес.
Sign up to leave a comment.

Articles