Scenario
We have two Solr cores, Product List and Store Locator. The “ProductList” stores the details of the product like ProductID, ProductName and ProductDescription. The “StoreLocator” stores the details of the stores like StoreID, ProductID, StoreLocation and ProductAvailability. This core provides us information about the store and product availability in each store.We need to display the product details and the store location (that are coming from two different cores) of each product in the solr response.
We have two Solr cores, Product List and Store Locator. The “ProductList” stores the details of the product like ProductID, ProductName and ProductDescription. The “StoreLocator” stores the details of the stores like StoreID, ProductID, StoreLocation and ProductAvailability. This core provides us information about the store and product availability in each store.We need to display the product details and the store location (that are coming from two different cores) of each product in the solr response.
Description of the handler
The newly created request handler in Solr named “/retrieve” will search for all records in ProductList core and then iterates through all the Solr documents to read the ProductID attribute. It then establishes a connection with the StoreLocator core and reads the StoreLocation attribute for each product based on this ProductID. Finally, the handler displays all the attributes from ProductList core along with the store location attribute from the StoreLocator core for each product.
The newly created request handler in Solr named “/retrieve” will search for all records in ProductList core and then iterates through all the Solr documents to read the ProductID attribute. It then establishes a connection with the StoreLocator core and reads the StoreLocation attribute for each product based on this ProductID. Finally, the handler displays all the attributes from ProductList core along with the store location attribute from the StoreLocator core for each product.
Steps to follow
Step 1 - Create new cores - ProductList and StoreLocator
Navigate to solr directory at ..\solr-4.3.1\example\solr and add the following lines (in bold) in solr.xml file -
<cores adminPath="/admin/cores" defaultCoreName="collection1" host="${host:}" hostPort="${jetty.port:8983}" hostContext="${hostContext:solr}"
zkClientTimeout="${zkClientTimeout:15000}">
<core name="collection1" instanceDir="collection1" />
<core name="ProductList" instanceDir="ProductList" />
<core name="StoreLocator" instanceDir="StoreLocator" />
</cores>
Navigate to solr directory at ..\solr-4.3.1\example\solr and add the following lines (in bold) in solr.xml file -
<cores adminPath="/admin/cores" defaultCoreName="collection1" host="${host:}" hostPort="${jetty.port:8983}" hostContext="${hostContext:solr}"
zkClientTimeout="${zkClientTimeout:15000}">
<core name="collection1" instanceDir="collection1" />
<core name="ProductList" instanceDir="ProductList" />
<core name="StoreLocator" instanceDir="StoreLocator" />
</cores>
Step 2 - Place the configuration files for ProductList core
Copy and paste the existing ‘collection1’ folder at ..\solr-4.3.1\example\solr. Now rename the folder as ‘ProductList’.
Step 3 - Schema Design for ProductList core
Navigate to conf folder at ..\solr-4.3.1\example\solr\ProductList\conf and add the following lines (in bold) in schema.xml file -
<fields>
<!--Product List -->
<field name="ProductID" type="string" indexed="true" stored="true" required="true"/>
<field name="ProductName" type="string" indexed="true" stored="true" required="false"/>
<field name="ProductDescription" type="string" indexed="true" stored="true" required="false"/>
…
…
</fields>
Please note that the unique key is the ProductID here.
Copy and paste the existing ‘collection1’ folder at ..\solr-4.3.1\example\solr. Now rename the folder as ‘ProductList’.
Step 3 - Schema Design for ProductList core
Navigate to conf folder at ..\solr-4.3.1\example\solr\ProductList\conf and add the following lines (in bold) in schema.xml file -
<fields>
<!--Product List -->
<field name="ProductID" type="string" indexed="true" stored="true" required="true"/>
<field name="ProductName" type="string" indexed="true" stored="true" required="false"/>
<field name="ProductDescription" type="string" indexed="true" stored="true" required="false"/>
…
…
</fields>
Please note that the unique key is the ProductID here.
Step 4 - Place the configuration files for StoreLocator core
Copy and paste the existing ‘collection1’ folder at ..\solr-4.3.1\example\solr\collection1. Now rename the folder as ‘StoreLocator’.
Copy and paste the existing ‘collection1’ folder at ..\solr-4.3.1\example\solr\collection1. Now rename the folder as ‘StoreLocator’.
Step 5 - Schema Design for StoreLocator core
Navigate to conf folder at ..\solr-4.3.1\example\solr\StoreLocator\conf and add the following lines (in bold) in schema.xml file -
<fields>
<!--Store Locator Details -->
<field name="StoreID" type="string" indexed="true" stored="true" required="true"/>
<field name="ProductID" type="string" indexed="true" stored="true" required="false"/>
<field name="StoreLocation" type="string" indexed="true" stored="true" required="false"/>
<field name="ProductAvailability" type="string" indexed="true" stored="true" required="false"/>
…
…
</fields>
Please note that the unique key is the StoreID here.
Navigate to conf folder at ..\solr-4.3.1\example\solr\StoreLocator\conf and add the following lines (in bold) in schema.xml file -
<fields>
<!--Store Locator Details -->
<field name="StoreID" type="string" indexed="true" stored="true" required="true"/>
<field name="ProductID" type="string" indexed="true" stored="true" required="false"/>
<field name="StoreLocation" type="string" indexed="true" stored="true" required="false"/>
<field name="ProductAvailability" type="string" indexed="true" stored="true" required="false"/>
…
…
</fields>
Please note that the unique key is the StoreID here.
Step 6 - Start the Solr sever
Step 7 - Indexing data into both the cores
Step 8 - Configure the Request Handler in both the cores
Configure the request handler in the solrconfig.xml of both the cores. The handler is configured to trigger in response to ‘../solr/retrieve’ request.
<requestHandler name="/retrieve" class="com.custom.solr.handlers.SolrJSearcher">
</requestHandler>
Configure the request handler in the solrconfig.xml of both the cores. The handler is configured to trigger in response to ‘../solr/retrieve’ request.
<requestHandler name="/retrieve" class="com.custom.solr.handlers.SolrJSearcher">
</requestHandler>
Step 9 - Create a custom subclass of RequestHandlerBase and override the handleRequestBody(SolrQueryRequest, SolrQueryResponse) method
package com.custom.solr.handlers;
import java.util.Iterator;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
/**
* Title : SolrJSearcher Description : Searches for all entries in ProductList collection and gets the ProductID entries.
* Makes a connection with the StoreLocation collection, for every ProductID retrieved in the above step, it queries and
* gets the corresponding StoreLocation. It displays the product details and the store location
* of each product in the Solr response.
*
* Revision History ----------------
*
* @version 1.0
* @author 5/22/15 sofia l {None.} Written Code
*/
public class SolrJSearcher extends RequestHandlerBase {
HttpSolrServer serverProductList = null;
HttpSolrServer serverStoreLocator = null;
static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(SolrJSearcher.class.getName());
public SolrJSearcher(){
serverProductList = new HttpSolrServer("http://localhost:8983/solr/ProductList");
serverStoreLocator = new HttpSolrServer("http://localhost:8983/solr/StoreLocator");
}
@Override
public String getDescription() {
return "SolrJSearcher";
}
@Override
public String getSource() {
return null;
}
@Override
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse resp) throws Exception {
String productID = null;
ModifiableSolrParams qparamsProductID=new ModifiableSolrParams();
qparamsProductID.add("q","*:*");
QueryResponse qresProductID=serverProductList.query(qparamsProductID);
SolrDocumentList resultsProductID=qresProductID.getResults();
SolrDocumentList resultsStoreLocation = null;
long numFoundProductID = qresProductID.getResults().getNumFound();
// Iterate through solr response
SolrDocument solrDocumentforProductID = null;
for (Iterator<SolrDocument> iterator = resultsProductID.iterator(); iterator.hasNext();) {
for (int i = 0; i < numFoundProductID; i++) {
solrDocumentforProductID = (SolrDocument) iterator.next();
productID = (String) solrDocumentforProductID.getFieldValue("ProductID");
ModifiableSolrParams qparamsStoreLocation=new ModifiableSolrParams();
qparamsStoreLocation.add("q","ProductID:" +productID);
QueryResponse qresStoreLocation=serverStoreLocator.query(qparamsStoreLocation);
resultsStoreLocation=qresStoreLocation.getResults();
long numFoundStoreLocation = qresStoreLocation.getResults().getNumFound();
// Iterate through solr response
SolrDocument solrDocumentforStoreLocation = null;
String storeLocation = null;
for (Iterator<SolrDocument> iterator1 = resultsStoreLocation.iterator();iterator1.hasNext();) {
for (int j = 0; j < numFoundStoreLocation; j++) {
solrDocumentforStoreLocation = (SolrDocument) iterator1.next();
storeLocation = (String) solrDocumentforStoreLocation.getFieldValue("StoreLocation");
solrDocumentforProductID.addField("StoreLocation", storeLocation);
}
}
}
resp.add("Results", resultsProductID);
}
}
}
Now compile the code and generate the jar file “SolrJSearcher.jar”.
Step 10 - Place the library files
Place all the required jar files (solr-solrj-4.3.1.jar, solr-core-4.3.1.jar and log4j-1.2.16.jar) including the SolrJSearcher.jar inside a directory named ‘handerlib’ at solrhome . Specify the path of the directory in the solrconfig.xml of both the cores as given below –
<lib dir="C:\..\..\..\solr-4.3.1\solr-4.3.1\example\solr\handlerlib" regex=".*\.jar" />
package com.custom.solr.handlers;
import java.util.Iterator;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
/**
* Title : SolrJSearcher Description : Searches for all entries in ProductList collection and gets the ProductID entries.
* Makes a connection with the StoreLocation collection, for every ProductID retrieved in the above step, it queries and
* gets the corresponding StoreLocation. It displays the product details and the store location
* of each product in the Solr response.
*
* Revision History ----------------
*
* @version 1.0
* @author 5/22/15 sofia l {None.} Written Code
*/
public class SolrJSearcher extends RequestHandlerBase {
HttpSolrServer serverProductList = null;
HttpSolrServer serverStoreLocator = null;
static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(SolrJSearcher.class.getName());
public SolrJSearcher(){
serverProductList = new HttpSolrServer("http://localhost:8983/solr/ProductList");
serverStoreLocator = new HttpSolrServer("http://localhost:8983/solr/StoreLocator");
}
@Override
public String getDescription() {
return "SolrJSearcher";
}
@Override
public String getSource() {
return null;
}
@Override
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse resp) throws Exception {
String productID = null;
ModifiableSolrParams qparamsProductID=new ModifiableSolrParams();
qparamsProductID.add("q","*:*");
QueryResponse qresProductID=serverProductList.query(qparamsProductID);
SolrDocumentList resultsProductID=qresProductID.getResults();
SolrDocumentList resultsStoreLocation = null;
long numFoundProductID = qresProductID.getResults().getNumFound();
// Iterate through solr response
SolrDocument solrDocumentforProductID = null;
for (Iterator<SolrDocument> iterator = resultsProductID.iterator(); iterator.hasNext();) {
for (int i = 0; i < numFoundProductID; i++) {
solrDocumentforProductID = (SolrDocument) iterator.next();
productID = (String) solrDocumentforProductID.getFieldValue("ProductID");
ModifiableSolrParams qparamsStoreLocation=new ModifiableSolrParams();
qparamsStoreLocation.add("q","ProductID:" +productID);
QueryResponse qresStoreLocation=serverStoreLocator.query(qparamsStoreLocation);
resultsStoreLocation=qresStoreLocation.getResults();
long numFoundStoreLocation = qresStoreLocation.getResults().getNumFound();
// Iterate through solr response
SolrDocument solrDocumentforStoreLocation = null;
String storeLocation = null;
for (Iterator<SolrDocument> iterator1 = resultsStoreLocation.iterator();iterator1.hasNext();) {
for (int j = 0; j < numFoundStoreLocation; j++) {
solrDocumentforStoreLocation = (SolrDocument) iterator1.next();
storeLocation = (String) solrDocumentforStoreLocation.getFieldValue("StoreLocation");
solrDocumentforProductID.addField("StoreLocation", storeLocation);
}
}
}
resp.add("Results", resultsProductID);
}
}
}
Now compile the code and generate the jar file “SolrJSearcher.jar”.
Step 10 - Place the library files
Place all the required jar files (solr-solrj-4.3.1.jar, solr-core-4.3.1.jar and log4j-1.2.16.jar) including the SolrJSearcher.jar inside a directory named ‘handerlib’ at solrhome . Specify the path of the directory in the solrconfig.xml of both the cores as given below –
<lib dir="C:\..\..\..\solr-4.3.1\solr-4.3.1\example\solr\handlerlib" regex=".*\.jar" />
No comments:
Post a Comment