diff --git a/CHANGES.txt b/CHANGES.txt index eefd8fe2407..abb26cc284c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -267,6 +267,8 @@ New Features HTMLStripStandardTokenizerFactory deprecated. To strip HTML tags, HTMLStripCharFilter can be used with an arbitrary Tokenizer. (koji) +68. SOLR-1367: Added callback mechanism for converting DocList to SolrDocumentList in SolrPluginUtils (gsingers) + Optimizations ---------------------- diff --git a/src/java/org/apache/solr/util/SolrDocumentModifier.java b/src/java/org/apache/solr/util/SolrDocumentModifier.java new file mode 100644 index 00000000000..49ab5da6bd7 --- /dev/null +++ b/src/java/org/apache/solr/util/SolrDocumentModifier.java @@ -0,0 +1,37 @@ +package org.apache.solr.util; +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.solr.common.SolrDocument; + + +/** + * Callback capability for modifying a SolrDocument in the {@link SolrPluginUtils#docListToSolrDocumentList(org.apache.solr.search.DocList, org.apache.solr.search.SolrIndexSearcher, java.util.Set, java.util.Map)} + * + *

+ * NOTE: This API is subject to change. + * Due to https://issues.apache.org/jira/browse/SOLR-1298 and https://issues.apache.org/jira/browse/SOLR-705, this interface may change in the future. + * + **/ +public interface SolrDocumentModifier { + /** + * Implement this method to allow for changes to be made to the {@link org.apache.solr.common.SolrDocument} in the {@link SolrPluginUtils#docListToSolrDocumentList(org.apache.solr.search.DocList, org.apache.solr.search.SolrIndexSearcher, java.util.Set, SolrDocumentModifier, java.util.Map)} + * call. + * @param doc The {@link org.apache.solr.common.SolrDocument} that can be modified. + */ + void process(SolrDocument doc); +} diff --git a/src/java/org/apache/solr/util/SolrPluginUtils.java b/src/java/org/apache/solr/util/SolrPluginUtils.java index 0763d72ce98..ae4a18445c5 100644 --- a/src/java/org/apache/solr/util/SolrPluginUtils.java +++ b/src/java/org/apache/solr/util/SolrPluginUtils.java @@ -887,26 +887,36 @@ public class SolrPluginUtils { } } - /** - * Convert a DocList to a SolrDocumentList - * - * The optional param "ids" is populated with the lucene document id - * for each SolrDocument. - * - * @param docs The {@link org.apache.solr.search.DocList} to convert - * @param searcher The {@link org.apache.solr.search.SolrIndexSearcher} to use to load the docs from the Lucene index - * @param fields The names of the Fields to load - * @param ids A map to store the ids of the docs - * @return The new {@link org.apache.solr.common.SolrDocumentList} containing all the loaded docs - * @throws java.io.IOException if there was a problem loading the docs - * @since solr 1.4 - */ + public static SolrDocumentList docListToSolrDocumentList( DocList docs, SolrIndexSearcher searcher, Set fields, Map ids ) throws IOException { + return docListToSolrDocumentList(docs, searcher, fields, null, ids); + } + + /** + * Convert a DocList to a SolrDocumentList + * + * The optional param "ids" is populated with the lucene document id + * for each SolrDocument. + * + * @param docs The {@link org.apache.solr.search.DocList} to convert + * @param searcher The {@link org.apache.solr.search.SolrIndexSearcher} to use to load the docs from the Lucene index + * @param fields The names of the Fields to load + * @param docModifier The {@link SolrDocumentModifier} + * @param ids A map to store the ids of the docs + * @return The new {@link org.apache.solr.common.SolrDocumentList} containing all the loaded docs + * @throws java.io.IOException if there was a problem loading the docs + * @since solr 1.4 + */ + public static SolrDocumentList docListToSolrDocumentList( + DocList docs, + SolrIndexSearcher searcher, + Set fields, SolrDocumentModifier docModifier, + Map ids ) throws IOException{ DocumentBuilder db = new DocumentBuilder(searcher.getSchema()); SolrDocumentList list = new SolrDocumentList(); list.setNumFound(docs.matches()); @@ -917,7 +927,7 @@ public class SolrPluginUtils { while (dit.hasNext()) { int docid = dit.nextDoc(); - + Document luceneDoc = searcher.doc(docid, fields); SolrDocument doc = new SolrDocument(); db.loadStoredFields(doc, luceneDoc); @@ -927,10 +937,14 @@ public class SolrPluginUtils { if (docs.hasScores()) { doc.addField("score", dit.score()); } else { - doc.addField("score", 0.0f); + doc.addField("score", 0.0f); + } + + if (docModifier != null) { + docModifier.process(doc); } list.add( doc ); - + if( ids != null ) { ids.put( doc, new Integer(docid) ); } @@ -938,6 +952,7 @@ public class SolrPluginUtils { return list; } + /** * Given a SolrQueryResponse replace the DocList if it is in the result. * Otherwise add it to the response diff --git a/src/test/org/apache/solr/util/SolrPluginUtilsTest.java b/src/test/org/apache/solr/util/SolrPluginUtilsTest.java index 4bbc2fde48c..ef948fe0e5b 100644 --- a/src/test/org/apache/solr/util/SolrPluginUtilsTest.java +++ b/src/test/org/apache/solr/util/SolrPluginUtilsTest.java @@ -19,6 +19,14 @@ package org.apache.solr.util; import org.apache.solr.util.SolrPluginUtils; import org.apache.solr.util.SolrPluginUtils.DisjunctionMaxQueryParser; +import org.apache.solr.core.SolrCore; +import org.apache.solr.search.SolrIndexSearcher; +import org.apache.solr.search.DocList; +import org.apache.solr.search.DocSlice; +import org.apache.solr.request.SolrQueryResponse; +import org.apache.solr.common.util.*; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.SolrDocumentList; import org.apache.lucene.index.Term; import org.apache.lucene.search.Query; @@ -27,12 +35,15 @@ import org.apache.lucene.search.PhraseQuery; import org.apache.lucene.search.DisjunctionMaxQuery; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.BooleanClause.Occur; import java.util.List; import java.util.Map; import java.util.HashMap; import java.util.Iterator; +import java.util.Set; +import java.util.HashSet; /** * Tests that the functions in SolrPluginUtils work as advertised. @@ -42,6 +53,36 @@ public class SolrPluginUtilsTest extends AbstractSolrTestCase { public String getSchemaFile() { return "schema.xml"; } public String getSolrConfigFile() { return "solrconfig.xml"; } + + public void testDocModifier() throws Exception { + assertU("", adoc("id", "3234", "val_t", "quick red fox")); + assertU("", adoc("id", "3235", "val_t", "quick green fox")); + assertU("", adoc("id", "3236", "val_t", "quick brown fox")); + commit(); + SolrIndexSearcher srchr = h.getCore().getSearcher().get(); + SolrIndexSearcher.QueryResult qr = new SolrIndexSearcher.QueryResult(); + SolrIndexSearcher.QueryCommand cmd = new SolrIndexSearcher.QueryCommand(); + cmd.setQuery(new MatchAllDocsQuery()); + qr = srchr.search(qr, cmd); + + DocList docs = qr.getDocList(); + Set fields = new HashSet(); + fields.add("val_t"); + + SolrDocumentModifier docMod = new SolrDocumentModifier() { + public void process(SolrDocument doc) { + doc.addField("junk", "foo"); + } + }; + + SolrDocumentList list = SolrPluginUtils.docListToSolrDocumentList(docs, srchr, fields, docMod, null); + assertTrue("list Size: " + list.size() + " is not: " + docs.size(), list.size() == docs.size()); + for (SolrDocument document : list) { + assertNotNull(document.get("junk")); + } + + } + public void testPartialEscape() { assertEquals("",pe(""));