Как объединить Hibernate Search (Lucene) с пейджингом и ACL - PullRequest
4 голосов
/ 17 ноября 2011

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

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 и затем выполнить подкачку вручную.Но мне не нравится это решение, потому что оно загружает все документы, а не только один для страницы.

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

Ответы [ 3 ]

4 голосов
/ 17 ноября 2011

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

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

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

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

2 голосов
/ 17 ноября 2011

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

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

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

0 голосов
/ 28 февраля 2013

Здесь - моя реализация ACL со сложной иерархической системой ACL «Пользователь / Группа / Роль» с использованием чисто запросов Lucene (поверх поиска Hibernate).

...