You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by to...@apache.org on 2015/02/11 16:12:44 UTC

svn commit: r1658983 - in /jackrabbit/oak/trunk: oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java

Author: tommaso
Date: Wed Feb 11 15:12:44 2015
New Revision: 1658983

URL: http://svn.apache.org/r1658983
Log:
OAK-2473 - added ACL checks for suggestions in Lucene and Solr indexes

Modified:
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
    jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java?rev=1658983&r1=1658982&r2=1658983&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java Wed Feb 11 15:12:44 2015
@@ -65,6 +65,7 @@ import org.apache.jackrabbit.oak.spi.que
 import org.apache.jackrabbit.oak.spi.query.QueryIndex.AdvanceFulltextQueryIndex;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.document.Document;
 import org.apache.lucene.index.FieldInfo;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.MultiFields;
@@ -347,11 +348,26 @@ public class LucenePropertyIndex impleme
                         noDocs = true;
                     } else if (luceneRequestFacade.getLuceneRequest() instanceof SuggestHelper.SuggestQuery) {
                         SuggestHelper.SuggestQuery suggestQuery = (SuggestHelper.SuggestQuery) luceneRequestFacade.getLuceneRequest();
+
                         List<Lookup.LookupResult> lookupResults = SuggestHelper.getSuggestions(suggestQuery);
+
+                        // ACL filter suggestions
                         Collection<String> suggestedWords = new ArrayList<String>(lookupResults.size());
-                        for (Lookup.LookupResult suggestWord : lookupResults) {
-                            suggestedWords.add("{term=" + suggestWord.key + ",weight=" + suggestWord.value + "}");
+                        QueryParser qp = new QueryParser(Version.LUCENE_47, FieldNames.FULLTEXT, indexNode.getDefinition().getAnalyzer());
+                        for (Lookup.LookupResult suggestion : lookupResults) {
+                            Query query = qp.createPhraseQuery(FieldNames.FULLTEXT, suggestion.key.toString());
+                            TopDocs topDocs = searcher.search(query, 100);
+                            if (topDocs.totalHits > 0) {
+                                for (ScoreDoc doc : topDocs.scoreDocs) {
+                                    Document retrievedDoc = searcher.doc(doc.doc);
+                                    if (filter.isAccessible(retrievedDoc.get(FieldNames.PATH))) {
+                                        suggestedWords.add("{term=" + suggestion.key + ",weight=" + suggestion.value + "}");
+                                        break;
+                                    }
+                                }
+                            }
                         }
+
                         queue.add(new LuceneResultRow(suggestedWords));
                         noDocs = true;
                     }

Modified: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java?rev=1658983&r1=1658982&r2=1658983&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java Wed Feb 11 15:12:44 2015
@@ -49,6 +49,7 @@ import org.apache.jackrabbit.oak.spi.que
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.client.solrj.response.SpellCheckResponse;
 import org.apache.solr.common.SolrDocument;
@@ -298,26 +299,7 @@ public class SolrQueryIndex implements F
                         if (suggest != null) {
                             Set<Map.Entry<String, Object>> suggestEntries = suggest.entrySet();
                             if (!suggestEntries.isEmpty()) {
-                                SolrDocument fakeDoc = new SolrDocument();
-                                for (Map.Entry<String, Object> suggestor : suggestEntries) {
-                                    SimpleOrderedMap<Object> suggestionResponses = ((SimpleOrderedMap) suggestor.getValue());
-                                    for (Map.Entry<String, Object> suggestionResponse : suggestionResponses) {
-                                        SimpleOrderedMap<Object> suggestionResults = ((SimpleOrderedMap) suggestionResponse.getValue());
-                                        for (Map.Entry<String, Object> suggestionResult : suggestionResults) {
-                                            if ("suggestions".equals(suggestionResult.getKey())) {
-                                                ArrayList<SimpleOrderedMap<Object>> suggestions = ((ArrayList<SimpleOrderedMap<Object>>) suggestionResult.getValue());
-                                                if (suggestions.isEmpty()) {
-                                                    fakeDoc.addField(QueryImpl.REP_SUGGEST, "[]");
-                                                }
-                                                else {
-                                                    for (SimpleOrderedMap<Object> suggestion : suggestions) {
-                                                        fakeDoc.addField(QueryImpl.REP_SUGGEST, "{term=" + suggestion.get("term") + ",weight=" + suggestion.get("weight") + "}");
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
+                                SolrDocument fakeDoc = getSuggestions(suggestEntries, filter);
                                 queue.add(new SolrResultRow("/", 1.0, fakeDoc));
                                 noDocs = true;
                             }
@@ -342,22 +324,49 @@ public class SolrQueryIndex implements F
         return cursor;
     }
 
-    void onRetrievedDocs(Filter filter, SolrDocumentList docs) {
-        // do nothing
-    }
+    private SolrDocument getSuggestions(Set<Map.Entry<String, Object>> suggestEntries, Filter filter) throws SolrServerException {
+        Collection<SimpleOrderedMap<Object>> retrievedSuggestions = new HashSet<SimpleOrderedMap<Object>>();
+        SolrDocument fakeDoc = new SolrDocument();
+        for (Map.Entry<String, Object> suggestor : suggestEntries) {
+            SimpleOrderedMap<Object> suggestionResponses = ((SimpleOrderedMap) suggestor.getValue());
+            for (Map.Entry<String, Object> suggestionResponse : suggestionResponses) {
+                SimpleOrderedMap<Object> suggestionResults = ((SimpleOrderedMap) suggestionResponse.getValue());
+                for (Map.Entry<String, Object> suggestionResult : suggestionResults) {
+                    if ("suggestions".equals(suggestionResult.getKey())) {
+                        ArrayList<SimpleOrderedMap<Object>> suggestions = ((ArrayList<SimpleOrderedMap<Object>>) suggestionResult.getValue());
+                        if (!suggestions.isEmpty()) {
+                            for (SimpleOrderedMap<Object> suggestion : suggestions) {
+                                retrievedSuggestions.add(suggestion);
+                            }
+                        }
+                    }
+                }
+            }
+        }
 
-    private boolean exists(SolrResultRow row, NodeState root) {
-        boolean result = true;
-        NodeState nodeState = root;
-        for (String n : PathUtils.elements(row.path)) {
-            if (nodeState.hasChildNode(n)) {
-                nodeState = nodeState.getChildNode(n);
-            } else {
-                result = false;
-                break;
+        // ACL filter suggestions
+        for (SimpleOrderedMap<Object> suggestion : retrievedSuggestions) {
+            SolrQuery solrQuery = new SolrQuery();
+            solrQuery.setParam("q", String.valueOf(suggestion.get("term")));
+            solrQuery.setParam("df", configuration.getCatchAllField());
+            solrQuery.setParam("q.op", "AND");
+            solrQuery.setParam("rows", "100");
+            QueryResponse suggestQueryResponse = solrServer.query(solrQuery);
+            SolrDocumentList results = suggestQueryResponse.getResults();
+            if (results != null && results.getNumFound() > 0) {
+                for (SolrDocument doc : results) {
+                    if (filter.isAccessible(String.valueOf(doc.getFieldValue(configuration.getPathField())))) {
+                        fakeDoc.addField(QueryImpl.REP_SUGGEST, "{term=" + suggestion.get("term") + ",weight=" + suggestion.get("weight") + "}");
+                        break;
+                    }
+                }
             }
         }
-        return result;
+        return fakeDoc;
+    }
+
+    void onRetrievedDocs(Filter filter, SolrDocumentList docs) {
+        // do nothing
     }
 
     static boolean isIgnoredProperty(String propertyName, OakSolrConfiguration configuration) {
@@ -451,8 +460,9 @@ public class SolrQueryIndex implements F
                         return PropertyValues.newDouble(currentRow.score);
                     }
                     // TODO : make inclusion of doc configurable
+                    Collection<Object> fieldValues = currentRow.doc.getFieldValues(columnName);
                     return currentRow.doc != null ? PropertyValues.newString(
-                            String.valueOf(currentRow.doc.getFieldValue(columnName))) : null;
+                            Iterables.toString(fieldValues != null ? fieldValues : Collections.emptyList())) : null;
                 }
 
             };



Re: svn commit: r1658983 - in /jackrabbit/oak/trunk: oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java

Posted by Chetan Mehrotra <ch...@gmail.com>.
Hi Tommaso,

On Wed, Feb 11, 2015 at 8:42 PM,  <to...@apache.org> wrote:
> if (filter.isAccessible(retrievedDoc.get(FieldNames.PATH))) {
> +                                        suggestedWords.add("{term=" + suggestion.key + ",weight=" + suggestion.value + "}");
> +                                        break;
> +                                    }

Any reason for encoding the term and weight in the string. Is the end
user expected to parse the result string and extract those values? It
would be better if they are explicitly accessible from the JCR
QueryResult Row

Chetan Mehrotra