SOLR-3825: added in optional logging of documents in a response

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1386613 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Grant Ingersoll 2012-09-17 13:46:59 +00:00
parent 362975cd8e
commit b7297c7f8d
3 changed files with 260 additions and 0 deletions

View File

@ -0,0 +1,107 @@
package org.apache.solr.handler.component;
/*
* 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 java.io.IOException;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.response.ResultContext;
import org.apache.solr.search.DocIterator;
import org.apache.solr.search.DocList;
/**
* Adds to the log file the document IDs that are sent in the query response.
* If document scores are available in the response (by adding the pseudo-
* column 'score' to the field list) then each document ID will be followed
* by its score, as in:
* <pre>
* "... hits=55 responseLog=22:0.71231794,44:0.61231794 status=0 ..."
* </pre>
*
* Add it to a requestHandler in solrconfig.xml like this:
* <pre class="prettyprint">
* &lt;searchComponent name="responselog" class="solr.ResponseLogComponent"/&gt;
*
* &lt;requestHandler name="/select" class="solr.SearchHandler"&gt;
* &lt;lst name="defaults"&gt;
*
* ...
*
* &lt;/lst&gt;
* &lt;arr name="components"&gt;
* &lt;str&gt;responselog&lt;/str&gt;
* &lt;/arr&gt;
* &lt;/requestHandler&gt;</pre>
*
* It can then be enabled at query time by supplying <pre>responseLog=true</pre>
* query parameter.
*/
public class ResponseLogComponent extends SearchComponent {
public static final String COMPONENT_NAME = "responseLog";
@Override
public void prepare(ResponseBuilder rb) throws IOException {}
@Override
public void process(ResponseBuilder rb) throws IOException {
SolrParams params = rb.req.getParams();
if (!params.getBool(COMPONENT_NAME, false)) return;
ResultContext rc = (ResultContext) rb.rsp.getValues().get("response");
if (rc.docs.hasScores()) {
processScores(rb, rc.docs);
} else {
processIds(rb, rc.docs);
}
}
protected void processIds(ResponseBuilder rb, DocList dl) {
StringBuilder sb = new StringBuilder();
for(DocIterator iter = dl.iterator(); iter.hasNext();) {
sb.append(iter.nextDoc())
.append(',');
}
if (sb.length() > 0) {
rb.rsp.addToLog("responseLog", sb.substring(0, sb.length() - 1));
}
}
protected void processScores(ResponseBuilder rb, DocList dl) {
StringBuilder sb = new StringBuilder();
for(DocIterator iter = dl.iterator(); iter.hasNext();) {
sb.append(iter.nextDoc())
.append(':')
.append(iter.score())
.append(',');
}
if (sb.length() > 0) {
rb.rsp.addToLog("responseLog", sb.substring(0, sb.length() - 1));
}
}
@Override
public String getDescription() {
return "A component that inserts the retrieved documents (and optionally scores) into the response log entry";
}
@Override
public String getSource() {
return "$URL$";
}
}

View File

@ -0,0 +1,60 @@
<?xml version="1.0" ?>
<!--
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.
-->
<!-- $Id: $
$Source: $
$Name: $
Config for testing responselog component
-->
<config>
<luceneMatchVersion>${tests.luceneMatchVersion:LUCENE_CURRENT}</luceneMatchVersion>
<requestHandler name="standard"
class="solr.StandardRequestHandler"></requestHandler>
<!-- Used to specify an alternate directory to hold all index data.
It defaults to "index" if not present, and should probably
not be changed if replication is in use. -->
<dataDir>${solr.data.dir:}</dataDir>
<!-- The DirectoryFactory to use for indexes.
solr.StandardDirectoryFactory, the default, is filesystem based.
solr.RAMDirectoryFactory is memory based and not persistent. -->
<directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.RAMDirectoryFactory}"/>
<searchComponent name="responselog" class="org.apache.solr.handler.component.ResponseLogComponent" />
<!-- Log retrievedDocs -->
<requestHandler name="withlog" class="org.apache.solr.handler.component.SearchHandler">
<lst name="defaults">
<str name="defType">dismax</str>
</lst>
<arr name="last-components">
<str>responselog</str>
</arr>
</requestHandler>
<requestHandler name="nolog" class="org.apache.solr.handler.component.SearchHandler">
<lst name="defaults">
<str name="defType">dismax</str>
</lst>
</requestHandler>
</config>

View File

@ -0,0 +1,93 @@
package org.apache.solr.handler.component;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.junit.BeforeClass;
import org.junit.Test;
/*
* 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.
*/
public class ResponseLogComponentTest extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeTest() throws Exception {
initCore("solrconfig-response-log-component.xml","schema12.xml");
assertNull(h.validateUpdate(adoc("id", "1", "subject", "aa")));
assertNull(h.validateUpdate(adoc("id", "2", "subject", "aa")));
assertNull(h.validateUpdate(adoc("id", "3", "subject", "aa")));
assertU(commit());
}
@Test
public void testToLogIds() throws Exception {
SolrQueryRequest req = null;
try {
String handler="withlog";
req = req("indent","true", "qt","withlog", "q","aa", "rows","2",
"fl","id,subject", "responseLog","true");
SolrQueryResponse qr = h.queryAndResponse(handler, req);
NamedList<Object> entries = qr.getToLog();
String responseLog = (String) entries.get("responseLog");
assertNotNull(responseLog);
assertTrue(responseLog.matches("\\d+,\\d+"));
} finally {
if (req != null) {
req.close();
}
}
}
@Test
public void testToLogScores() throws Exception {
SolrQueryRequest req = null;
try {
String handler="withlog";
req = req("indent","true", "qt","withlog", "q","aa", "rows","2",
"fl","id,subject,score", "responseLog","true");
SolrQueryResponse qr = h.queryAndResponse(handler, req);
NamedList<Object> entries = qr.getToLog();
String responseLog = (String) entries.get("responseLog");
assertNotNull(responseLog);
assertTrue(responseLog.matches("\\d+:\\d+\\.\\d+,\\d+:\\d+\\.\\d+"));
} finally {
if (req != null) {
req.close();
}
}
}
@Test
public void testDisabling() throws Exception {
SolrQueryRequest req = null;
try {
String handler="withlog";
req = req("indent","true", "qt","withlog", "q","aa", "rows","2",
"fl","id,subject", "responseLog","false");
SolrQueryResponse qr = h.queryAndResponse(handler, req);
NamedList<Object> entries = qr.getToLog();
String responseLog = (String) entries.get("responseLog");
assertNull(responseLog);
} finally {
if (req != null) {
req.close();
}
}
}
}