Применение Clickhouse для ускорения поиска номенклатуры

18.08.24

Задачи пользователя - Поиск данных

В этой статье я хочу рассмотреть еще один кейс применения Clickhouse в связке с 1С - оптимизацию поиска в справочнике по ключевым словам. Здесь не будет готового решения, но будут описаны важные моменты, которые позволят легко применить данный кейс в реальности.

В последние годы использование высокопроизводительных аналитических баз данных стало критически важным для бизнеса, стремящегося эффективно анализировать большие объёмы данных и принимать обоснованные решения. Одним из ведущих решений в этой области является ClickHouse — колоночная система управления базами данных, известная своей скоростью и масштабируемостью. Однако, для многих компаний, использующих 1С:Предприятие в качестве основной системы автоматизации бизнеса, интеграция с такими современными инструментами, как ClickHouse, может представляться сложной задачей.

Радует, что на портале Infostart.ru начали появляться статьи, посвящённые применению ClickHouse в связке с 1С. Их пока не так много, можно найти в поиске по ключевому слову "clickhouse". Эти материалы стали отличным ресурсом для специалистов, стремящихся освоить новые инструменты и повысить производительность своих решений.

В этой статье я хочу рассмотреть еще один кейс применения это базы данных в связке с 1С - оптимизацию поиска номенклатуры по ключевым словам с применением Clickhouse. Здесь не будет готового решения, но будут описаны важные моменты, которые позволят легко применить данный кейс в реальности.

 

Итак, концепт задачи

 

Так как 1С при использовании стандартного поиска платформа строит не оптимальные запросы с использованием LIKE, это приводит к замедлению работы, особенно в случае, когда поиск осуществляется по нескольким ключевым словам(при интенсивной параллельной работе клиент даже может входить в ступор на минуты). Наиболее заметно это проявляется при поиске номенклатуры, когда в справочнике от 500к элементов. Поэтому есть смысл вынести непосредственно поиск кодов номенклатуры по наименованию, полному наименованию, артикулу и прочим полям в отдельную базу данных, которая умеет это делать достаточно быстро, чтобы она возвращала список найденных кодов, а 1С по этим кодам выбирала номенклатуру используя индекс, что тоже происходит быстро. Есть уверенность, что прирост производительности будет заметен невооруженным взглядом, поэтому синхронизацию на постоянной основе делаем сразу.

 

Подготовим базу данных

 

На просторах интернета куча информации, как поднять кликхаус. Для академических целей можно поднять самому в докере локально, а для прода - поручить системному администратору. Считаем, что развернутый экземпляр кликхауза у нас есть. Хочу только сказать, что несмотря на то, что в системных требования кликхауза упоминается минимум 32 гб оперативной памяти, для данной задачи достаточно будет виртуалочки с 4 гб. Должен быть опубликован порт 8123(http), мы в дальнейшем будем обращаться именно по http. Также будет удобно поднять tabix, это браузерный клиент для clickhouse, очень удобно для подготовки таблиц и отладки запросов.

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

Создадим базу данных и таблицу:

CREATE DATABASE ones_fastsearch

CREATE TABLE ones_fastsearch.sku (

  `code` String,

  `search` String,

  `name` String,

  `working` Bool

) ENGINE = ReplacingMergeTree

ORDER BY code

Обратите внимание, используем RepacingMergeTree, которая отличается от MergeTree тем, что выполняет удаление дублирующихся записей с одинаковым значением ключа сортировки (секция ORDER BY)

 

Синхронизируем номенклатуру

 

Теперь нужно научить 1С пополнять эту нашу таблицу на постоянной основе.

Это удобно делать асинхронно. Так все будет происходить в фоне и никому не будет мешать. Создадим очередь обработки измененной номенклатуры, которую будем наполнять при записи номенклатуры, а разбирать регламентным заданием, которое будет синхронизировать справочник.

РС ОчередьИнтеграцииНоменклатурыДляПодбора.

 

 

Модуль менеджера регистра

Процедура ДобавитьНоменклатуруВОчередь(СсылкаМассивСсылок) Экспорт 
	
	УстановитьПривилегированныйРежим(Истина);
	Если ТипЗнч(СсылкаМассивСсылок) = Тип("СправочникСсылка.Номенклатура") Тогда     
		
		МассивНоменалатуры = Новый Массив;
		МассивНоменалатуры.Добавить(СсылкаМассивСсылок); 
		ДобавитьНоменклатуруВОчередь(МассивНоменалатуры);
		
	Иначе   
		
		НаборЗаписей = РегистрыСведений.ОчередьИнтеграцииНоменклатурыДляПодбора.СоздатьНаборЗаписей();
		ДатаДобавленияМС = ТекущаяУниверсальнаяДатаВМиллисекундах();
		Для Каждого Номенклатура Из СсылкаМассивСсылок Цикл
			НоваяСтрокаНаборЗаписей = НаборЗаписей.Добавить();
			НоваяСтрокаНаборЗаписей.УникальныйИдентификатор = Новый УникальныйИдентификатор;
			НоваяСтрокаНаборЗаписей.Номенклатура = Номенклатура;
			НоваяСтрокаНаборЗаписей.ДатаДобавленияМС = ДатаДобавленияМС;
			НоваяСтрокаНаборЗаписей.ДатаДобавления = '00010101' + НоваяСтрокаНаборЗаписей.ДатаДобавленияМС / 1000;
		КонецЦикла;
		НаборЗаписей.Записать(Ложь);
		
	КонецЕсли;
	
КонецПроцедуры       


Процедура ПометитьОбработанным(УникальныйИдентификатор) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	МенеджерЗаписи = РегистрыСведений.ОчередьИнтеграцииНоменклатурыДляПодбора.СоздатьМенеджерЗаписи();
	МенеджерЗаписи.УникальныйИдентификатор = УникальныйИдентификатор;
	МенеджерЗаписи.Удалить();
	УстановитьПривилегированныйРежим(Ложь);
	
КонецПроцедуры

 

Общий модуль ИнтеграцияНоменклатураДляПодбораПовтИсп (как видно из именования, он серверный). Предполагаем, что у нас уже есть КоннекторHTTP (https://github.com/vbondarevsky/Connector). Если захочется повторить, придется самостоятельно организовать получение параметров для подключения к кликхаузу (у вас не будет модуля ИнтеграцииВызовСервераПовтИсп). Для академических целей можно просто захардкодить.

Функция ПараметрыДляЗапросовКХ() Экспорт   

	ПараметрыИнтеграции = ИнтеграцииВызовСервераПовтИсп.ПараметрыИнтеграции(Справочники.Интеграции.ИнтеграцияНоменклатураДляПодбора);
	
	Результат = Новый Структура;
	
	Результат.Вставить("Адрес", ПараметрыИнтеграции.СоответствиеПараметров["Адрес"]);
	Результат.Вставить("БазаданныхТаблица", ПараметрыИнтеграции.СоответствиеПараметров["БазаданныхТаблица"]);
	
	Результат.Вставить("ПараметрыHTTP", КоннекторHTTPВызовСервера.НовыеПараметры());
	
	Результат.ПараметрыHTTP.Вставить("Аутентификация", Новый Структура); 
	Результат.ПараметрыHTTP.Аутентификация.Вставить("Пользователь", ПараметрыИнтеграции.СоответствиеПараметров["Логин"]);
	Результат.ПараметрыHTTP.Аутентификация.Вставить("Пароль", ПараметрыИнтеграции.СоответствиеПараметров["Пароль"]);
	
	Результат.ПараметрыHTTP.Заголовки.Вставить("Content-Type", "application/text;encoding=utf-8");
	Результат.ПараметрыHTTP.Вставить("Таймаут", 5);        
	Результат.ПараметрыHTTP.Вставить("РазрешитьПеренаправление", Ложь);
	Результат.ПараметрыHTTP.Вставить("МаксимальноеКоличествоПовторов", 0);
	Результат.ПараметрыHTTP.Вставить("ПараметрыЗапроса", Новый Соответствие);     
	
	Возврат Результат;
	
КонецФункции

Функция ПараметрыКликхауза() Экспорт 
	
	ПараметрыИнтеграции = ИнтеграцииВызовСервераПовтИсп.ПараметрыИнтеграции(Справочники.Интеграции.ИнтеграцияНоменклатураДляПодбора);
	Результат = Новый Структура;                                                

	Результат.Вставить("АдресКликхаус", ПараметрыИнтеграции.СоответствиеПараметров["Адрес"]);
	Результат.Вставить("Логин", ПараметрыИнтеграции.СоответствиеПараметров["Логин"]);
	Результат.Вставить("Пароль", ПараметрыИнтеграции.СоответствиеПараметров["Пароль"]);
	Результат.Вставить("БазаданныхТаблица", ПараметрыИнтеграции.СоответствиеПараметров["БазаданныхТаблица"]);
	
	Возврат Результат;
	
КонецФункции  

Общий модуль ИнтеграцияНоменклатураДляПодбора. Обратите внимание, все в привилегированном режиме, чтобы не париться с ролями. Процедура ТочкаВходаРегламентноеЗаданиеИнтеграцияНоменклатурыДляПодбора() отправляет изменения в кликхаус добавлением. А так как мы для таблицы используем ReplacingMergeTree, кликхаус самостоятельно дедуплицирует записи тогда, когда посчитает нужным. Но не следует думать, что у нас будут дубли, поскольку в КодыНоменклатурыПоСтрокеПоиска() мы используем ключевое слово FINAL, которое дедуплицирует недодуплицированные записи непосредственно в момент выборки.

Процедура ТочкаВходаРегламентноеЗаданиеИнтеграцияНоменклатурыДляПодбора()
	
	УстановитьПривилегированныйРежим(Истина);
	
	ИнтеграцияНоменклатураДляПодбора.ПроверитьЧтоВсеПараметрыЗаполнены(); 
		
	ПараметрыКХ = ИнтеграцияНоменклатураДляПодбораПовтИсп.ПараметрыДляЗапросовКХ();
	ТекущаяДатаМС = ТекущаяУниверсальнаяДатаВМиллисекундах();
	
	Запрос = Новый Запрос;                                                                     
	Запрос.УстановитьПараметр("ТекущаяДатаМС", ТекущаяДатаМС);
	Запрос.Текст = "ВЫБРАТЬ
	               |	Очередь.УникальныйИдентификатор КАК УникальныйИдентификатор,
	               |	Очередь.Номенклатура КАК Ссылка,
	               |	Очередь.ДатаДобавленияМС КАК Порядок
	               |ПОМЕСТИТЬ ВТТаблицаСущностей
	               |ИЗ
	               |	РегистрСведений.ОчередьИнтеграцииНоменклатурыДляПодбора КАК Очередь
	               |ГДЕ
	               |	Очередь.ДатаДобавленияМС <= &ТекущаяДатаМС
	               |;
	               |
	               |////////////////////////////////////////////////////////////////////////////////
	               |ВЫБРАТЬ
	               |	ВТТаблицаСущностей.Ссылка КАК Ссылка
	               |ПОМЕСТИТЬ ВТСсылки
	               |ИЗ
	               |	ВТТаблицаСущностей КАК ВТТаблицаСущностей
	               |
	               |СГРУППИРОВАТЬ ПО
	               |	ВТТаблицаСущностей.Ссылка
	               |;
	               |
	               |////////////////////////////////////////////////////////////////////////////////
	               |ВЫБРАТЬ
	               |	Номенклатура.Код КАК Код,
	               |	Номенклатура.Наименование КАК Наименование,
	               |	Номенклатура.АльтернативноеНаименование КАК АльтернативноеНаименование,
	               |	Номенклатура.Артикул КАК Артикул,
	               |	Номенклатура.Бренд КАК Бренд,
	               |	Номенклатура.ОЕМ КАК ОЕМ,
	               |	Номенклатура.Рабочая КАК Рабочая
	               |ИЗ
	               |	ВТСсылки КАК ВТСсылки
	               |		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
	               |		ПО ВТСсылки.Ссылка = Номенклатура.Ссылка
	               |
	               |УПОРЯДОЧИТЬ ПО
	               |	Номенклатура.Код
	               |;
	               |
	               |////////////////////////////////////////////////////////////////////////////////
	               |ВЫБРАТЬ
	               |	ВТТаблицаСущностей.УникальныйИдентификатор КАК УникальныйИдентификатор,
	               |	ВТТаблицаСущностей.Ссылка КАК Ссылка
	               |ИЗ
	               |	ВТТаблицаСущностей КАК ВТТаблицаСущностей
	               |
	               |УПОРЯДОЧИТЬ ПО
	               |	УникальныйИдентификатор";
	РезультатыЗапросов = Запрос.ВыполнитьПакет();  
	ВыборкаИдентификаторы = РезультатыЗапросов[РезультатыЗапросов.ВГраница()].Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);    
	ВыборкаДанные = РезультатыЗапросов[РезультатыЗапросов.ВГраница() - 1].Выбрать();    
	
	МассивТекстовЗапроса = Новый Массив;
	МассивТекстовЗапроса.Добавить(СтрШаблон("INSERT INTO %1 (code, search, name, working) FORMAT JSONCompactEachRow", ПараметрыКХ.БазаданныхТаблица));
	
	ПараметрыЗаписиJSON = Новый Структура;
	ПараметрыЗаписиJSON.Вставить("ПереносСтрок", ПереносСтрокJSON.Нет);
	Пока ВыборкаДанные.Следующий() Цикл
		
		МассивДанныхНоменклатуры = Новый Массив;                       
		МассивДанныхНоменклатуры.Добавить(ВыборкаДанные.Код);   
		МассивДанныхНоменклатуры.Добавить(СтрШаблон("%1 %2 %3 %4 %5 %6", 
														ВыборкаДанные.Код, 
														ВыборкаДанные.Наименование,
														ВыборкаДанные.АльтернативноеНаименование,
														ВыборкаДанные.Артикул, 
														ВыборкаДанные.Бренд, 
														ВыборкаДанные.ОЕМ)
										);
		МассивДанныхНоменклатуры.Добавить(ВыборкаДанные.Наименование);
		МассивДанныхНоменклатуры.Добавить(ВыборкаДанные.Рабочая);
		МассивТекстовЗапроса.Добавить(КоннекторHTTPВызовСервера.ОбъектВJson(МассивДанныхНоменклатуры, , ПараметрыЗаписиJSON));
		
	КонецЦикла;

	//инсерт в клик    
	ТекстИнсерта = СтрСоединить(МассивТекстовЗапроса, Символы.ПС);
	ПараметрыHTTP = ПараметрыКХ.ПараметрыHTTP;
	Ответ = КоннекторHTTPВызовСервера.Post(ПараметрыКХ.Адрес, ТекстИнсерта, ПараметрыHTTP);
	Если Ответ.КодСостояния <> 200 Тогда 
		ВызватьИсключение(СтрШаблон("Сервер ответил %1 с телом %2", XMLСтрока(Ответ.КодСостояния), КоннекторHTTPВызовСервера.КакТекст(Ответ)));
	КонецЕсли;
	
	//скажем, что все огонь
	Пока ВыборкаИдентификаторы.Следующий() Цикл
		РегистрыСведений.ОчередьИнтеграцииНоменклатурыДляПодбора.ПометитьОбработанным(ВыборкаИдентификаторы.УникальныйИдентификатор);
	КонецЦикла;
	
КонецПроцедуры

Функция КодыНоменклатурыПоСтрокеПоиска(Знач СтрокаПоискаНоменклатуры) Экспорт
	
    //экранируем, защищаемся от sql инъекций
	СтрокаПоискаНоменклатуры = СтрЗаменить(СтрокаПоискаНоменклатуры, "'", "''");
	СтрокаПоискаНоменклатуры = СтрЗаменить(СтрокаПоискаНоменклатуры, "\", "\\");      
	
    // считаем, что если ищут >5 слов, ищут точное совпадение
	МассивПодстрок = СтрРазделить(СтрокаПоискаНоменклатуры, " ");  
	Если МассивПодстрок.Количество() > 5 Тогда
		МассивПодстрок = Новый Массив;
		МассивПодстрок.Добавить(СтрокаПоискаНоменклатуры);
	КонецЕсли;
	
	Результат = Новый Массив;
	
	УстановитьПривилегированныйРежим(Истина);
	
	ПараметрыКХ = ИнтеграцияНоменклатураДляПодбораПовтИсп.ПараметрыДляЗапросовКХ();
	
	МассивТекстовЗапроса = Новый Массив;
	МассивТекстовЗапроса.Добавить(СтрШаблон("SELECT
	|	groupArray(code)
	|FROM
	|	%1 FINAL
	|WHERE 
	|	working = TRUE", ПараметрыКХ.БазаданныхТаблица));
	
	Для Каждого Подстрока Из МассивПодстрок Цикл
        //не забываем для русского языка нужны функции *UTF8
		МассивТекстовЗапроса.Добавить(СтрШаблон("AND positionCaseInsensitiveUTF8(search, '%1') > 0", Подстрока));
	КонецЦикла;
	
	МассивТекстовЗапроса.Добавить("LIMIT 500");
	МассивТекстовЗапроса.Добавить("FORMAT TabSeparated"); //в сочетании с одной колонкой в выборке и агрегированием в groupArray() в одну строку
	//результат будет массивом JSON

	ТекстСелекта = СтрСоединить(МассивТекстовЗапроса, Символы.ПС);
	ПараметрыHTTP = ПараметрыКХ.ПараметрыHTTP;
	Ответ = КоннекторHTTPВызовСервера.Post(ПараметрыКХ.Адрес, ТекстСелекта, ПараметрыHTTP);
	Если Ответ.КодСостояния <> 200 Тогда 
		ВызватьИсключение(СтрШаблон("Сервер ответил %1 с телом %2", XMLСтрока(Ответ.КодСостояния), КоннекторHTTPВызовСервера.КакТекст(Ответ)));
    КонецЕсли;        

	Результат = КоннекторHTTPВызовСервера.КакJSON(Ответ)

    Возврат Результат;
	
КонецФункции

//падает, если какой-то параметр не заполнен
Функция ПроверитьЧтоВсеПараметрыЗаполнены() Экспорт
	
	ПараметрыИнтеграции = ИнтеграцииВызовСервераПовтИсп.ПолучитьПараметрыИнтеграции(Справочники.Интеграции.ИнтеграцияНоменклатураДляПодбора);
	ИнтеграцияНоменклатураДляПодбора.УпастьЕслиПараметрНеЗаполнен(ПараметрыИнтеграции.СоответствиеПараметров, "Адрес");
	ИнтеграцияНоменклатураДляПодбора.УпастьЕслиПараметрНеЗаполнен(ПараметрыИнтеграции.СоответствиеПараметров, "Логин");
	ИнтеграцияНоменклатураДляПодбора.УпастьЕслиПараметрНеЗаполнен(ПараметрыИнтеграции.СоответствиеПараметров, "Пароль");
	ИнтеграцияНоменклатураДляПодбора.УпастьЕслиПараметрНеЗаполнен(ПараметрыИнтеграции.СоответствиеПараметров, "БазаданныхТаблица");
	
КонецФункции

Процедура УпастьЕслиПараметрНеЗаполнен(Где, ИмяПараметра) Экспорт 
	
	Если Не ЗначениеЗаполнено(Где[ИмяПараметра]) Тогда
		ВызватьИсключение СтрШаблон("У интеграции ИнтеграцияНоменклатураДляПодбора не заполнен параметр %1", ИмяПараметра);
	КонецЕсли;
	
КонецПроцедуры

В номенклатуре напишем что-то вроде:

Процедура ПриЗаписи(Отказ)
    ...
    ...
	Если Не ЭтоГруппа Тогда 
		Если мЭтоНовый 
			или мСтарыеВерсииРеквизитовДляОбмена.Наименование <> Наименование 
			или мСтарыеВерсииРеквизитовДляОбмена.АльтернативноеНаименование <> АльтернативноеНаименование 
			или мСтарыеВерсииРеквизитовДляОбмена.Артикул <> Артикул
			или мСтарыеВерсииРеквизитовДляОбмена.Бренд <> Бренд
			или мСтарыеВерсииРеквизитовДляОбмена.Описание <> Описание
			или мСтарыеВерсииРеквизитовДляОбмена.ОЕМ <> ОЕМ
			или мСтарыеВерсииРеквизитовДляОбмена.Рабочая <> Рабочая
			Тогда
			РегистрыСведений.ОчередьИнтеграцииНоменклатурыДляПодбора.ДобавитьНоменклатуруВОчередь(Ссылка);
		КонецЕсли;
	КонецЕсли;
    ...
    ...
КонецПроцедуры

 

Создаем регламентное задание нужной частоты срабатывания процедуры ТочкаВходаРегламентноеЗаданиеИнтеграцияНоменклатурыДляПодбора()

Осталось запустить начальную синхронизацию, добавив всю рабочую номенклатуру в РС ОчередьИнтеграцииНоменклатурыДляПодбора.

 

Проверим, устроит ли нас производительность.

 

 

60-90 мс на 145000 записей номенклатуры (ведь не обязательно синхронизировать весь справочник 500к, если можно только рабочие?). Вполне себе неплохо. В конечном счете еще будет запрос в 1С с фильтром по кодам.

 

Непосредственно поиск

 

Мне неизвестно, какая у вас форма подбора. Вероятно, это управляемые формы и динамический список. Если так, то вот пример, как можно сделать.

&НаСервере
Процедура СтрокаПоискаНоменклатурыПриИзмененииНаСервере()
	
	СтрокаПоискаНоменклатуры = СокрЛП(СтрокаПоискаНоменклатуры);
	Если ИспользоватьВПодбореПоискНоменклатурыВКликхаузе Тогда
		
		//этот метод по умолчанию очищает все, что содержит группа
		ГруппаИ = ОбщегоНазначенияКлиентСервер.СоздатьГруппуЭлементовОтбора(СправочникНоменклатура.Отбор.Элементы, "общий поиск", ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ); 
		
		Если СтрокаПоискаНоменклатуры <> "" Тогда    
			МассивКоды = ИнтеграцияНоменклатураДляПодбора.КодыНоменклатурыПоСтрокеПоиска(СтрокаПоискаНоменклатуры);
			ОбщегоНазначенияКлиентСервер.ДобавитьЭлементКомпоновки(ГруппаИ, "Код", ВидСравненияКомпоновкиДанных.ВСписке,
			МассивКоды, , Истина, РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Обычный);
		КонецЕсли;
		
	Иначе

 

Как было

 

После набора поисковой строки клиент замирал на 2-8 секунд в среднем. В отдельных случаях в часы высокой нагрузки мог замирать на минуту.

 

Как стало

 

В результате мы получили инструмент:

  1. Более производительный.
  2. С ожидаемым временем исполнения на уровне трети-половины секунды на любой поисковый запрос.

 

Всем добра!

 

В заключение хочется сказать что применение ClickHouse в связке с 1С открывает перед бизнесом новые возможности для оптимизации различных процессов, выходящих за рамки традиционного анализа журнала регистрации. Рассмотренный кейс оптимизации поиска номенклатуры демонстрирует, как сочетание возможностей ClickHouse по производительности и 1С может значительно повысить производительность системы и ускорить выполнение задач, критически важных для бизнеса.

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

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

clickhouse кликхаус оптимизация поиска быстродействие номенклатура подбор быстрый поиск товаров

См. также

Поиск данных Внешние источники данных Системный администратор Программист Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Если вам нужно автоматически генерировать представления (view) к вашей базе данных 1С (есть две версии - для СУБД MS SQL Server и для PostgreSQL) по структуре метаданных 1С, то вам необходима данная обработка. Наш "Генератор View", другими словами - это коннектор к данным 1С для Power BI - незаменимый помощник для бизнес-аналитиков, работающих с базами 1С из Yandex Datalens/Power BI и т.д. Работает для обычных и управляемых форм под 1С 8.3

230000 руб.

31.07.2020    13815    13    48    

25

Поиск данных Системный администратор Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Обработки помогут Вам легко и, главное, быстро (в 5 раз и быстрее штатной обработки 1С), выполнить поиск дублирующих данных в Ваших базах 1С на платформах 8.1-8.3. Это позволит уменьшить объем лишней информации в справочниках и документах, планах видов характеристик и др., упростит работу с данными пользователям. А так же можно, одним нажатием, узнать в каких ссылочных объектах есть вообще дубли! Понятное расположение команд и настроек, в сочетании с описанием и справкой, еще упростят процесс. А так же обновления Вы получаете бесплатно в течение года с момента приобретения данных обработок! (Обновление от 27.11.2023, версия 6.12)

10800 руб.

14.05.2012    159076    337    253    

571

Математика и алгоритмы Инструментарий разработчика Универсальные функции Поиск данных Программист Платформа 1С v8.3 Конфигурации 1cv8 1С:ERP Управление предприятием 2 Абонемент ($m)

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

5 стартмани

25.09.2024    2291    0    Артано    14    

19

Поиск данных Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Отображение и просмотр реквизитов справочника или документа - с бесконечным открытием подуровней.

1 стартмани

14.06.2024    3450    7    RustIG    26    

22

Поиск данных Системный администратор Программист Платформа 1С v8.3 Россия Абонемент ($m)

Статья об опыте развертывания и интеграции с базой данных Manticore Search для быстрого полнотекстового поиска.

1 стартмани

30.11.2023    4651    andreysidor4uk    18    

53

Поиск данных Корректировка данных Пользователь Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

PowerOffice - обработка для поиска, просмотра и обработки данных для пользователей. Доступ к объектам на просмотр и редактирование данных определяется правами пользователя.

1 стартмани

05.06.2023    2344    25    PowerBoy    1    

15

Поиск данных Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Получение ссылки в 1С по бинарной строке из PostgreSQL в виде строки формата bytea или из MSSQL в виде шестнадцатиричной строки. Кроме ссылочных объектов ссылки могут быть получены и для перечислений. Это может быть полезно при анализе логов журнала регистрации или СУБД.

1 стартмани

04.04.2023    3158    4    berserg    2    

12
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Xershi 1557 18.08.24 19:13 Сейчас в теме
Хорошо, а что если переписать поиск 1С на запросы самостоятельно?
3. 1cnik2 14 19.08.24 07:39 Сейчас в теме
(1) это был первый вариант. в статье второй, и он быстрее
2. user612295_death4321 19.08.24 07:06 Сейчас в теме
Можно уточнить, почему для решения узкой поисковой задачи была выбрана именно колоночная субд, а не специализированная СУБД под поиск, которую можно гибко тюнинговать под задачи поиска? Например тот же эластик?
starik-2005; comol; +2 Ответить
4. 1cnik2 14 19.08.24 08:14 Сейчас в теме
(2) у нас нет эластика в стеке. предлагаю вам написать аналогичную статью с описанием как применить эластик.
5. AlexEuro 19.08.24 10:45 Сейчас в теме
https://infostart.ru/1c/articles/1984277/ а с таким решением сравнивали ? а как работает с частями слов(типа рад%ка) ?
6. 1cnik2 14 19.08.24 11:31 Сейчас в теме
(5) К сожалению, нет. Была задача решить проблему как можно быстрее.
1. С кликхаусом уже был знаком.
2. Быстродействие ожидаемо хорошо.
3. Системные требования минимальны.
Вообще говоря, это форма подбора, которая дополнительно запрашивает еще и цены, и остатки, и другую информацию. И, учитывая это, большой разницы нет - 10 мс будет поиск или 80. Все равно реакция на клиенте будет на уровне 300-800 мс

Благодарю за полезную ссылку!
7. comol 5109 19.08.24 12:20 Сейчас в теме
мы используем ключевое слово FINAL, которое дедуплицирует недодуплицированные записи непосредственно в момент выборки
расстрел
10. 1cnik2 14 19.08.24 19:53 Сейчас в теме
(7) поясните, что конкретно вам не нравится?
8. comol 5109 19.08.24 12:24 Сейчас в теме
Одни ЖР сгружают в эластик, другие из clickhouse полнотекст пытаются сделать.... Не надо так вообщем - clickhouse для аналитических запросов, которые подразумевают слово "аггрегация"... вместо 1С:Аналитики с ДатаАкселератором - проще быстрее и дешевле. Остатки можно собрать без таблиц итогов, можнго огромный массив сгрузить и сжать... но не для поиска строки... я думаю решение вашей задачи имело смысл искать на уровне 1С, либо вам в elastic всё таки... или как там opensearch теперь бесплатный аналог. CH тут не в тему
user612295_death4321; +1 Ответить
13. user612295_death4321 20.08.24 14:29 Сейчас в теме
(8)
Одни ЖР сгружают в эластик, другие из clickhouse полнотекст пытаются сделать


Комментарий просто бомба)
9. starik-2005 3090 19.08.24 17:44 Сейчас в теме
В свое время делал "комплитер" для поиска контрагентов по условно такой строке "альфа воронеж центр" (можно и "аль вор цен", а можно и "fkm djh wty"). На 300к контрагентов без всех этих не1Сных систем работало в реальном времени. Три символа вводишь - понеслось. Для этого просто использовалась табличная часть еще одного справочника, в которой были указаны строки маленькими буквами без пробелов для русского/латинского и транслита в обе стороны. Искалось все через "ПОДОБНО" (для первых 3-х букв, первые 50), остальные слова искались в найденном обычным циклом через тогда еще "Если Найти(Слово, Строка) > 0 Тогда..."..

Так что я вообще вот не представляю, нафига городить этот огород ради того, что прям на 1С-ном языке делается за условные единицы часов...

ЗЫ: в части ROI, то количество исправлений документов сократилось на 80%.
ЗЫЗЫ: было это 10 лет назад.
11. comol 5109 19.08.24 21:07 Сейчас в теме
(10) final заставляет ch налету мерджить парты.... Т.е. выключая все те оптимизации для которых как раз парты и нужны. Не говоря уже о самом движке replacing.... Если уж хотите сделать ch больно и использовать его вместо эластика то хотя бы после обновления таблицы напишите optimize table final.... Или используйте collapsing merge tree и сверните дубли на уровне запроса или вообще в 1С. Но так топорно не надо. Об этом собственно жирным кажется написано в документации
12. 1cnik2 14 20.08.24 07:06 Сейчас в теме
(11) а чем конкретно в данном случае collapsing merge tree лучше replacing? https://clickhouse.com/docs/en/guides/developer/deduplication

И, раз уж мы тут, скажите, как по-вашему лучше хранить справочники в clickhouse? Номенклатуру, контрагентов, менеджеров, у которых есть свойства и эти свойства меняются со временем?
14. Silenser 612 20.08.24 15:58 Сейчас в теме
(15) Если у вас длина наименования небольшая (не более 150 символов) и вы обычно ищете по одному слову, то полнотекстовый поиск 1С, ИМХО, был бы более оптимальным решением. Вы бы остались в рамках более узкого стека приложений, вам бы не требовалось узкоспециальных знаний для поддержки. Ну и скорость была бы сопоставима, при условии, что мы же не код в рамках транзакции разрабатываем, так что реакция на уровне 0.5 с и 0.05 с будет вполне сопоставимой, люди не ощутят разницу.
15. 1cnik2 14 21.08.24 07:59 Сейчас в теме
(14) не согласен:
1. Разница 0.5 и 0.05 это на порядок, разница ощутима.
2. Стабильность(а точнее, нестабильность) полнотекстового поиска в 1С - притча во языцех.
16. starik-2005 3090 21.08.24 15:40 Сейчас в теме
(15)
нестабильность
Не знаю, кто влепил минус, но у нас индекс полнотекстового поиска падает раз в неделю, занимает дофига места и не помогает ни разу. Т.е. LIKE работает быстрее, чем оное непойми что.
18. Silenser 612 21.08.24 15:44 Сейчас в теме
(16) я это случайно мышью ткнул не туда, убрал уже. По теме: у нас ППД используется на постоянке, штука крайне зависимая от платформы, мы теперь перед релизом на прод стали и ППД тестировать. Как уже писал выше, на 8.3.22 ППД ломался часто, где-то пару раз в месяц, а вот на текущей 23й платформе живет довольно стабильно.
19. starik-2005 3090 21.08.24 15:46 Сейчас в теме
(18)
на текущей 23й платформе живет довольно стабильно
У нас 24-я. На 21-й падал регулярно. На текущей падает временами. Но в части скорости такое себе...
20. Silenser 612 21.08.24 16:14 Сейчас в теме
(19) В 24й писали про ускорение ППД, если я правильно помню, но для этого ускорения индекс нужно было перестроить с нуля, перестраивали?
17. Silenser 612 21.08.24 15:40 Сейчас в теме
(15) вот тут вообще с Вами не согласен
1. Ради интереса посмотрите среднее время реакции водителя в ПДД, это даст вам представление о том, что разницы для 99.9% людей между 0.05 и 0.5 с нет, человек реагирует медленнее, он просто не успеет оценить разницу, для него эти интервалы времени будут одинаковы. Если бы мы говорили о времени проведения документа, то согласен, это была бы огромная разница, но для интерфейсной функции такая скорость попросту излишня, это как в квартиру вместо звонка корабельный ревун ставить, а вместе с расширением стека делает решение неоптимальным, с моей точки зрения, конечно.
2. Все очень сильно зависит от наполнения базы и ее размера и версии платформы. В данный момент у меня на продуктиве клиентский сервис использует ППД на постоянке по 12 часов в день. С 8.3.22.1750 индекс нужно было перестраивать 1-2 раза в месяц, а на 8.3.23.1342 за 4 месяца перестроить его пришлось только 1 раз. Размер индекса 300 Гб, в базе около 300 пользователей онлайн, из которых человек 10-20 в работе используют ППД на постоянной основе, это часть их функционала. На мой взгляд - это более чем стабильно, даже SLA в таком раскладе выходит 99.6%, более чем достойный показатель.
21. 1cnik2 14 22.08.24 10:40 Сейчас в теме
(17) попробую переубедить.
1. Все верно говорите, но не нужно забывать, что помимо поиска есть еще получение цен, остатков, аналогов и всего прочего. У нас это занимает еще примерно 300-500 мс на выведенный список, и это отдельная история. Так что если только поиск вместо 0.1 сек будет 0.5 сек, то общее время кардинально увеличится и выйдет за пределы реакции пользователя.
2. Посчитайте, сколько вы возитесь с полнотекстовым поиском. Перестроения, внезапные падения и прочее каждый месяц, сидишь с ним, как на пороховой бочке. А тут - поставил и забыл. Коллеги выше верно говорят, что, вероятно, лучше использовать специализированную базу данных именно для поиска, ElasticSearch или Manticore Search. Там больше возни с внедрением, зато со стабильностью на порядок лучше.
22. Silenser 612 22.08.24 14:58 Сейчас в теме
(21)
1. Мне кажется вы путаете теплое с мягким - одно дело полнотекстовый поиск для нахождения нужного объекта системы среди текстовых записей, другое - получение остатков и цен. Для первого подойдет любой полнотекстовый поиск, даже в MS SQL. Для второго явно напрашиваются регистры и, если я правильно понял, то CH для их поиска в вашем варианте не используется вообще. А раз так, зачем вообще рассуждать о дополнительных затратах поиска структурированной информации о ценах и остатках и приводить это как доказательство, если эта часть задачи с CH не связана вообще?
2. Поскольку система рабочая, то точно могу сказать, т.к. обслуживание выполнялось вне рабочего времени и оплачивалось отдельно. На каждый инцидент - 30 минут: дождаться окончания регзаданий, очистить и запустить формирование. В месяц выходило около часа. Кстати, вы же понимаете, что CH тоже нужно обслуживать.
23. 1cnik2 14 24.08.24 16:47 Сейчас в теме
(22) 1. Нет, вам неправильно кажется
2. По поводу обслуживания кх, оно специфично для задачи. В данном случае он просто крутится, и внимания не требует
Оставьте свое сообщение