Короткий вопрос:
Я ищу способ (Java) перехватить запрос к Solr и ввести несколько дополнительных параметров фильтрации, предоставляемых моей бизнес-логикой. Какие структуры я должен использовать?
Контекст:
Прежде всего, небольшое признание: я такой новичок в отношении Solr. Для меня настройка сервера, определение схемы, кодирование функционального менеджера индексов, а затем фактическое отображение сервера, возвращающего правильные результаты - именно так, как и предполагалось! - было уже большим достижением для себя. Ты меня!
Однако в настоящее время я работаю над корпоративным проектом, который требует немного большего. Грубо говоря, экземпляр solr должен запрашиваться несколькими тысячами пользователей через один и тот же requestHandler, поскольку возвращаемые документы автоматически фильтруются в соответствии с уровнем разрешений пользователя. Например, если пользователь A и суперпользователь B будут использовать одни и те же параметры поиска (даже один и тот же URL-адрес), пользователь B получит все файлы пользователя A, а затем еще несколько. Для этого документы уже проиндексированы с необходимой информацией об уровне разрешений.
Что ж, учитывая это и используя обширную документацию Solr для начинающих разработчиков, я попытался придумать простой пользовательский requestHandler, который переопределяет функцию handleRequest для добавления необходимых дополнительных параметров в SolrQueryRequest. Все в порядке, но я не вижу никакой разницы в QueryResponse, сервер грубо игнорирует мои небольшие манипуляции. После нескольких дней поиска в Интернете без особого намека на погоду, если это лучший подход, наконец-то решил прийти и побеспокоить хороших людей здесь, в StackOverflow.
Итак, вкратце, мои вопросы:
Это правильный подход? Есть ли другие альтернативы? Я уже могу понять некоторые концепции Солра, но по общему признанию, многого не хватает, и вполне возможно, что чего-то не хватает.
Если так, то после изменения параметров запроса мне нужно что-то предпринять, чтобы принудительно обновить QueryResponse? Насколько я могу судить, они просто инкапсулируют http-запросы, и мне не удается прослушать что-либо, запрашивающее сервер после внесения изменений.
Заранее спасибо и очень жаль за длинный пост!
UPDATE
После долгих чтений API и особенно проб и ошибок мне удалось найти функциональное решение. Однако я до сих пор не могу понять большую часть внутренностей Солра, поэтому все равно был бы признателен за некоторое просветление. Не стесняйтесь бить по желанию, я все еще очень осведомлен о моей новизне.
Соответствующей частью решения является эта функция, которая вызывается переопределенной handleRequestBody:
private void SearchDocumentsTypeII(SolrDocumentList results,
SolrIndexSearcher searcher, String q,
UserPermissions up, int ndocs, SolrQueryRequest req,
Map<String, SchemaField> fields, Set<Integer> alreadyFound)
throws IOException, ParseException {
BooleanQuery bq = new BooleanQuery();
String permLvl = "PermissionLevel:" + up.getPermissionLevel();
QParser parser = QParser.getParser(permLvl, null, req);
bq.add(parser.getQuery(), Occur.MUST);
Filter filter = CachingWrapperFilter(new QueryWrapperFilter(bq));
QueryParser qp = new QueryParser(q, new StandardAnalyzer());
Query query = qp.parse(q);
append (results, searcher.search(
query, filter, 50).scoreDocs,
alreadyFound, fields, new HashMap<String,Object>(), 0,
searcher.getReader(), true);
}
По сути, поисковый запрос никак не изменяется, и вместо этого применяется фильтр, содержащий PermissionLevel пользователя. Несмотря на это, почему не работает следующая альтернатива? Поисковый запрос отлично работает, когда применяется в стандартном requestHandler, тогда как в этом случае он просто не попадает ни в один документ.
private void SearchDocumentsTypeII(SolrDocumentList results,
SolrIndexSearcher searcher, String q,
UserPermissions up, int ndocs, SolrQueryRequest req,
Map<String, SchemaField> fields, Set<Integer> alreadyFound)
throws IOException, ParseException {
String qFiltered = q + " AND " + "PermissionLevel:" + up.getPermissionLevel();
QueryParser qp = new QueryParser(qFiltered, new StandardAnalyzer());
Query query = qp.parse(qFiltered);
append (results, searcher.search(
query, null, 50).scoreDocs,
alreadyFound, fields, new HashMap<String,Object>(), 0,
searcher.getReader(), true);
}