у меня тупой вопрос всем участвующим. Вот насколько нормально использовать методы класса Search? Я всех своих новых программеров учу не использовать данный способ, а учиться правильно делать вьюхи.
Если коротко - it depends.
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Развернуто</div></div><div class="sp-body"><div class="sp-content">
Вьюха - дорогое удовольствие, и на нагруженной системе она зачастую протухшая(неактуальная).
Делаю вьюху только если реально упираюсь в производительность. В общем случае, search работает крайне быстро(правда есть известные проблемы с поиском при наличии окурков в базе ).
В случае, когда код выполняется на клиенте, а в коллекции много документов - разница слабоуловима, т.к. основное время тратится не на поиск, а на обход коллекции клиентом.
Если предполагается, что в коллекции будет много документов - я предпочту search. Если миллионная база, а в результаты поиска попадет 5-10 доков , то, возможно, сделаю вьюху.
Есть большая коллекция документов, и для каждого дока в коллекции нужен лукап в другую базу - тут лучше вьюху: тыща view.getDocumentByKey значительно выиграет у тыщи db.search(но опять же, при условии, что не переполучаем вьюху тыщу раз).
В общем тема нетривиальная, и правильный ответ: it depends. Ну и нельзя забывать классику про "преждевременную оптимизацию"
История 1:
Серверный агент строит отчет, база полмиллиона доков, на выходе генерица xml. Работает крайне медленно. Проблема в db.search? В большом количестве доков? Отнюдь! Проблема в том, что для формирования xml используется конкатенация строк: xml = xml + .... Замена string на stream - и время работы сократилось в четыре(!) раза
История 2:
Пользователи регулярно выполняют поиск товара в каталоге(30K документов): на входе строка, на выходе - достаточно сложный поисковый запрос по нескольким полям. Пользователи на плохом канале жалуются, что "все тормозит". Расследование показывает, что сам db.search выполняется мнгновенно ( < 1 сек ), что неудивительно, ибо search всегда выполняется на сервере и от ширины канала не зависит. Проблема - долгий обход коллекции на клиенте. Решение: использование недокументированного collection.getNoteIds и кэширование документов(точнее объектов, считанных из документов) на клиенте. <div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">class GoodsRepo</div></div><div class="sp-body"><div class="sp-content">
Код:
Private cache List As ProductInfo '' use noteid as keys
Public Function search(query As String) As SearchResponse
.....
Set collection = t_db.Search( sf$, Nothing, 0 )
If collection.Count > 0 Then
Forall noteId In collection.getNoteIds()
If Not Iselement(cache(noteId)) Then
Set cache(noteId) = '' получили док по NoteId, сформировали экземпляр GoodInfo
End If
Call response.add(cache(noteId))
End Forall
End If
Set search = response
End Function
Результат: т.к. обычно ищут примерно одно и тоже ( актуальное наличие ~ 1000 позиций ), то большинство позиций оказываются кэшированными на клиенте и в итоге все "летает"
и что подобное будет намного быстрее работать, к примеру на базе с 140т.документами (около 10-ти форм) и объёмом около 10гб (в базе, ещё, есть разграничение по видимости, но в данном моменте, его исключим)?
В вашем конкретном случае(в предположении, что по заданной форме примерно 14K доков) быстрее работать не будет. Основное время уйдет на обход коллекции. Ну и пример нетиповой: отобрать все доки по заданной форме в базе на 140k доков - это скорее всего какая-то серверная задача(отчет? его можно предвычислять и пользоваться инкрементальными алгоритмами), либо служебный код(который обычно не критичен к времени отклика: рассылки, формирование суточных/недельных/квартальных отчетов, прочие ночные агенты). Конечному пользователю коллекция такого размера обычно не нужна.