Оптимизация слинг-запросов

У меня есть компонент cq5, которому нужно запросить заданный путь для пары других типов компонентов, например:

    String query = "select * from nt:unstructured where jcr:path like '/content/some/path/%' and ( contains(sling:resourceType, 'resourceType1') or contains(sling:resourceType, 'resourceType2')) ";
    Iterator<Resource> resources = resourceResolver.findResources( query,"sql");

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


person Ben Newman    schedule 21.01.2014    source источник


Ответы (2)


<сильный>1. Используйте более конкретный тип JCR, чем nt:unstructured.

Я предполагаю, что вы ищете узлы страницы, поэтому попробуйте cq:Page или (еще лучше) cq:PageContent.

<сильный>2. Денормализация данных.

Если я правильно понимаю ваш запрос, он должен возвращать страницы, содержащие ресурс1 или ресурс2. Вместо использования предиката contains(), который очень затратен и не позволяет JCR использовать индекс, пометьте страницы, содержащие эти ресурсы, дополнительным атрибутом. Например, установите соответствующие свойства jcr:content/containsResource1 и jcr:content/containsResource2, а затем используйте их в своем запросе:

select * from cq:PageContent where (containsResource1 is not null or containsResource2 is not null) and jcr:path like '/content/some/path/%'

Вы можете использовать EventHandler или SlingPostProcessor для автоматической установки свойств при добавлении ресурса1 или ресурса2.

person Tomek Rękawek    schedule 22.01.2014

Я добавил теги "jackrabbit" и "jcr" к вашему вопросу - я не эксперт в запросах JCR, но один из этих экспертов может захотеть прокомментировать оператор запроса, который вы используете, и если и как это можно оптимизировать.

При этом ваше утверждение «время ожидания страницы», по-видимому, подразумевает, что это клиентский браузер, который истекает, поскольку он не получает данные слишком долго. Я бы сначала проверил (с помощью отладчика или операторов журнала), действительно ли это вызов findResources, который занимает слишком много времени, или виноват код, который запускается после этого.

Если findResources работает медленно, вам потребуется оптимизировать запрос или изменить код, чтобы сделать его асинхронным, например, чтобы клиентский код сначала получал HTML-страницу, а затем получал результаты запроса с помощью асинхронных вызовов.

Если код, который запускается после findResources, вызывает тайм-аут, вы можете переделать его, чтобы начать отправку данных в браузер как можно скорее, и регулярно очищать вывод, чтобы избежать тайм-аутов. Но если вы найдете много результатов, которые в любом случае могут занять у пользователя слишком много времени, тогда также потребуется более асинхронное поведение.

person Bertrand Delacretaz    schedule 22.01.2014