Логика же!

Submitted by 0xd34df00d on Sat, 02/28/2009 - 16:36

Образ
(Кликабельно, 139kB)

Что делает ca:lyrics (chevelle - blank earth OR tool - bottom) OR ca:d OR ca:h t:w cs:off *.pdf? Это который на скриншоте. Да, кстати, он эквивалентен более длинному category:lyrics (chevelle - blank earth OR tool - bottom) OR category:downloads OR category:history type:wildcard casesensitivity:off *.pdf, если раскрыть все сокращения. Он выполняет четыре элементарных подзапроса — находит тексты соответствующих песен, показывает список закачек и выполняет поиск по истории с маской *.pdf, и объединяет результаты.

Как это работает: сначала функция парсинга запросов упрощает запрос — удаляет все лишние пробелы и парные скобки по краям, находит все OR'ы, разрезает запрос пополам вместо OR'а и рекурсивно вызывает сама себя. Если OR'ов нет — аналогично для AND'а. Как раз получается, что приоритет AND'а выше приоритета OR'а, что логично, потому что:

  • Курс булевой алгебры.
  • AND сужает область поиска, поэтому лучше вызывать сначала его.
  • Это логично.

Если и AND'ов нет, но скобки остались, то преобразует выражение типа expr1 (expr2 OP expr3) в expr1 expr2 OR expr1 expr3 и опять же вызывается уже для него. Если осталось банальное выражение expr — строит на его основе элементарный подзапрос.

Таким образом, строится граф, в узлах которого стоят классы, объединяющие результаты из дочерних узлов согласно заданной операции (либо, собственно, объединение, либо пересечение), а в листьях — классы, выполняющие сам поиск. Вершина дерева передается вьюшке, и все получается очень хорошо и не сильно медленно, пока юзер не начинает городить ну очень стремные запросы, которые делают дерево глубоким.

Еще одно преимущество графов — не нужно раскрывать скобки вида expr1 OP1 (expr2 OP2 expr3), выражение под скобками естественным образом становится дочерним для OP1.

После написания кучи поисковых плагинов можно будет развернуться на полную!