Solr Custom RequestHandler - внедрение параметров запроса - PullRequest
4 голосов
/ 31 мая 2011

Короткий вопрос: Я ищу способ (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);

}

Ответы [ 3 ]

2 голосов
/ 31 мая 2011

Хорошая новость: вам не нужно писать какой-либо код для этого, вам просто нужно правильно настроить Solr.Суперпользователь будет обращаться к стандартному обработчику запросов, в то время как обычный пользователь будет обращаться к другому обработчику запросов (также solr.StandardRequestHandler), настроенному с инвариантом с запросом фильтра, который вы хотите навязать им.

Смотрите также http://wiki.apache.org/solr/SolrRequestHandler

1 голос
/ 02 июня 2011

Ну хорошо.Как уже говорилось ранее, ответ, который работал для меня.Не стесняйтесь комментировать или bash!

   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);
        }
0 голосов
/ 31 мая 2011

Взгляните на эту вики-страницу solr, на которой написано, что мы должны сначала рассмотреть вопрос об использовании Apache Manifold Framework , и, если она не удовлетворяет вашим потребностям, то напишите свой собственный requestHandler

...