2011-11-17 7 views
4

Я использую Spring Security с ACL для защиты документов в своем приложении. С другой стороны, я использую Hibernate Search (поверх lucene) для поиска документов. Этот поиск также поддерживает подкачку. (документы только метаданные документов, хранящихся в базе данных.)Как совместить Hibernate Search (Lucene) с пейджингом и ACL

FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); 
QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Document.class).get(); 
Query query = queryBuilder.keyword().onFields(fieldNames.toArray(new String[0])).matching(searchQuery) 
      .createQuery(); 

FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(query, Document.class); 
fullTextQuery.setFirstResult(pageable.getFirstItem()); 
fullTextQuery.setMaxResults(pageable.getPageSize()); 

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

У кого-нибудь есть идея?

ответ

2

У меня тоже такая же проблема, и я не думаю, что есть простой ответ.

Я думаю, что есть только два решения. Тот, который вы предложили, который имеет проблемы с производительностью, которые вы описали, поскольку вам необходимо загрузить документы и разрешить ACL для каждого результата, а затем выполнить собственный пейджинг. Альтернативой является продвижение этой работы на сторону индексирования и индексация вашего ACL в Lucene. Это дает вам результаты поиска, скрывая результаты, которые пользователь не может видеть, добавляя условия фильтрации на основе текущего пользователя/группы/разрешений/ролей, но за счет поддержания индекса с информацией ACL. Если ваш ACL прост, это может быть вариант. Если ваш ACL является иерархическим, то он по-прежнему является вариантом, но более сложным. Его также сложно держать ваш индекс в курсе ACL.

Тот факт, что вы начинаете изучать эту функциональность, может указывать на то, что вы начинаете растягивать ваше решение Database/Hibernate/Lucene. Может быть, репозиторий контента, такой как Jackrabbit, может быть лучше подходит? Я предполагаю, что это, вероятно, слишком далеко, но, возможно, стоит взглянуть на то, как он это делает. В качестве альтернативы взгляните на SOLR, в частности на этот issue, который описывает, какова тернистая проблема.

4

Если ваш ACL не слишком сложный, то есть у вас есть небольшое, конечное количество уровней, то я предлагаю использовать Filter и Bitset для его реализации.

И здесь вы найдете дополнительные примеры реализации ACL с фильтрами http://java.dzone.com/articles/how-implement-row-level-access

Здесь вы найдете кешированную реализацию BitSet фильтра, который был в производстве в течение не менее 5 лет (это мой с открытым исходным кодом веб-приложение для поиск параллельный текст корпус)

Посмотрите на метод addSourceFilter http://code.google.com/p/hunglish-webapp/source/browse/trunk/src/main/java/hu/mokk/hunglish/lucene/LuceneQueryBuilder.java

0

Here моя реализация ACL со сложными пользователей/групп/Роль системы иерархического ACL с помощью чистые запросы Lucene (в верхней части Hibernate Search).

Смежные вопросы