Subversion Repositories SmartDukaan

Rev

Rev 1720 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package in.shop2020.social.services;

import in.shop2020.config.ConfigException;
import in.shop2020.thrift.clients.config.ConfigClient;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;


import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

/**
 * 
 * @author Varun Gupta
 *
 */

public class SolrSearchService {
        
        /**
         * 
         */
        public static final String SOLR_URL;
        
        static {
                String solr_url = null;
                try {
                        solr_url = ConfigClient.getClient().get("solr_url");
                }catch(ConfigException cex){
                        cex.printStackTrace();
                        solr_url = "http://localhost:8983/solr/select/";
                }
                SOLR_URL = solr_url;
        }
        
        /**
         * 
         */
        private XPath xpath;
        
        /**
         * 
         */
        private InputSource inputSource;
        
        TreeMap<String,HashMap<String,Integer>> facetMap;
        
        List<String> resultMap;
        
        long numberOfResults=0;
        /**
         * 
         * @param query
         * @param facetDefinitionIDs
         */
        public SolrSearchService(String query, String[] facetqueries, String[] facetDefinitionIDs, long start, long rows,  Double minPrice, Double maxPrice, long categoryId, String sortOrder) {
                
                this.xpath = XPathFactory.newInstance().newXPath();
                
        // if multiple words are given, it should do AND for all of them
        if(query.contains(" ")){
                String[] tokens = query.split("\\s+");
                query = tokens[0];
                for(int i = 1; i < tokens.length; i++){
                        query = query + " AND " + tokens[i];
                }
        }
        
                String uri = SOLR_URL + "?wt=xml&q=" + query;
                
                uri += "&stats=on&stats.field=F_50002";


                if(minPrice != null || maxPrice != null){
                        String minString = "0";
                        String maxString = "*";  
                        if(minPrice != null){
                                minString = minPrice.toString();
                        }
                        if(maxPrice != null){
                                maxString = maxPrice.toString();
                        }
                        uri += "&fq=F_50002:["+  minString + " " + maxString + "]";
                }
                
                if(categoryId != 10000){
                        //TODO: Call to CategoryManager to be resolved later
//                      uri += "&fq=F_50010:\"" + CategoryManager.getCategoryManager().getCategoryLabel(categoryId) + "\"";
                }
                
                if(sortOrder != null){
                        uri += "&sort=" + sortOrder;
                }
                
                if(facetqueries != null) {
                        for(int i=0; i<facetqueries.length; i++) {
                                if(facetqueries[i].contains(" ") && !facetqueries[i].contains("F_50002")){
                                        String[] tokens = facetqueries[i].split(":");
                                        uri += "&fq=" + tokens[0] + ":\"" + tokens[1] + "\"";
                                }else{
                                        uri += "&fq=" + facetqueries[i] + "";
                                }
                        }
                }
                uri += "&fl=ID,Name&facet=true&start=" + start + "&rows=" + rows;
                
                for(int i=0; i<facetDefinitionIDs.length; i++) {
                        uri += "&facet.field=" + facetDefinitionIDs[i];
                }

                this.inputSource = new InputSource(uri);

                this.facetMap = getFacetMap();
        }

        public TreeMap<String,HashMap<String,Integer>> removeUnwantedFacets(TreeMap<String,HashMap<String,Integer>> facetMap, long numberOfResults){
                TreeMap<String,HashMap<String,Integer>> tempFacets = new TreeMap<String, HashMap<String,Integer>>(); 
                for(String facet : facetMap.keySet()){
                        if(facetMap.get(facet).size() > 1){
                                HashMap<String,Integer> tempMap = new HashMap<String, Integer>();
                                
                                for(String facetValueName : facetMap.get(facet).keySet()){
                                        if(facetMap.get(facet).get(facetValueName) != 0 && facetMap.get(facet).get(facetValueName) != numberOfResults){
                                                tempMap.put(facetValueName, facetMap.get(facet).get(facetValueName));
                                        }
                                }
                                if(!tempMap.isEmpty()){
                                        tempFacets.put(facet, tempMap);
                                }
                        }       
                }
                if(tempFacets.containsKey("F_50010")){
                        tempFacets.remove("F_50011");
                }

                return tempFacets;
        }
        
/*
        int sumOfFacetCounts = 0;
        for(String facetValueName : facetMap.get(facet).keySet()){
                if(facetMap.get(facet).get(facetValueName) == 0 || facetMap.get(facet).get(facetValueName) == numberOfResults){
                        tempFacets.get(facet).remove(facetValueName);
                        // FIXME
                        /
                        HashMap<String, Integer> tmp = tempFacets.get(facet);
                        tmp.remove(facetValueName);
                        tempFacets.put(facet, tmp);
                        /
                }else{
                        sumOfFacetCounts += facetMap.get(facet).get(facetValueName);
                }
        }
        if(sumOfFacetCounts < numberOfResults*PERCENTAGE_OF_TOTAL_RESULTS/100){
                tempFacets.remove(facet);
        }
}

*/
        public HashMap<String,Integer> getFacetDetails(String facetName){
                return facetMap.get(facetName);
        }
        
        public TreeMap<String,HashMap<String,Integer>> getFacetMap() {
                facetMap = new TreeMap<String,HashMap<String,Integer>>();
                
                String facetNamePath = "/response/lst/lst[@name = 'facet_fields']/lst";
                
                NodeList nodes = null;
                try {
                        nodes = (NodeList) this.xpath.evaluate(facetNamePath, this.inputSource, XPathConstants.NODESET);
                }
                catch (XPathExpressionException xpee) {
                        return null;
                }
                
                if(nodes.getLength() == 0) {
                        return null;
                }
                
                NodeList subNodes = null;
                String facetName = new String();
                
                for(int i=0; i<nodes.getLength(); i++) {
                        Node node = nodes.item(i);
                        facetName = node.getAttributes().getNamedItem("name").getNodeValue();
                        subNodes = node.getChildNodes();
                        HashMap<String,Integer> facetValueCountMap = new HashMap<String,Integer>();
                        for(int j=0; j<subNodes.getLength(); j++) {
                                Node subNode = subNodes.item(j);
                                if(Integer.parseInt(subNode.getTextContent())==0)
                                                continue;
                                facetValueCountMap.put(subNode.getAttributes().getNamedItem("name").getNodeValue(), Integer.parseInt(subNode.getTextContent()));
                        }
                        facetMap.put(facetName, facetValueCountMap);
                        }
                System.out.println(facetMap);
                
                this.numberOfResults  = this.getTotalResults();
                
                facetMap = removeUnwantedFacets(facetMap, numberOfResults);
                System.out.println(facetMap);
                return facetMap;
                }
        
        public List<String> getResultMap() {
                resultMap = new LinkedList<String>();

                String resultDocsPath = "/response/result/doc";
                
                
                NodeList nodes = null;
                try {
                        nodes = (NodeList) this.xpath.evaluate(resultDocsPath, this.inputSource, XPathConstants.NODESET);
                }
                catch (XPathExpressionException xpee) {
                        return null;
                }
                
                if(nodes.getLength() == 0) {
                        return null;
                }
                
                for(int i=0; i<nodes.getLength(); i++) {
                        Node node = nodes.item(i);
                        String docID = node.getFirstChild().getTextContent();
                        resultMap.add(docID);   
                }
                System.out.println("resultMap is " + resultMap);
                return resultMap;
        }

        public HashMap<String, Double> getPriceStatsMap() {
                HashMap<String, Double> priceStatsMap = new HashMap<String, Double>();

                String resultDocsPath = "/response/lst[@name = 'stats']/lst[@name = 'stats_fields']/lst[@name = 'F_50002']";
                
                
                NodeList nodes = null;
                try {
                        nodes = (NodeList) this.xpath.evaluate(resultDocsPath, this.inputSource, XPathConstants.NODESET);
                }
                catch (XPathExpressionException xpee) {
                        return null;
                }
                
                if(nodes.getLength() == 0) {
                        return null;
                }
                
                NodeList subNodes = nodes.item(0).getChildNodes();
                
                for(int i=0; i<subNodes.getLength(); i++) {
                        Node node = subNodes.item(i);
                        
                        String parameter = node.getAttributes().getNamedItem("name").getNodeValue();
                        String value = node.getTextContent();
                        priceStatsMap.put(parameter, Double.parseDouble(value));        
                }
                System.out.println("priceStatsMap is " + priceStatsMap);
                return priceStatsMap;
        }

        public HashMap<String,Integer> getRangeQueryResultMap() {
                HashMap<String, Integer> rangeQueryResultMap = new HashMap<String,Integer>();

                String resultDocsPath = "/response/lst[@name = 'facet_counts']/lst[@name = 'facet_queries']/int";
                
                
                NodeList nodes = null;
                try {
                        nodes = (NodeList) this.xpath.evaluate(resultDocsPath, this.inputSource, XPathConstants.NODESET);
                }
                catch (XPathExpressionException xpee) {
                        return null;
                }
                
                if(nodes.getLength() == 0) {
                        return null;
                }
                
                
                for(int i=0; i<nodes.getLength(); i++) {
                        Node node = nodes.item(i);

                        String query = node.getAttributes().getNamedItem("name").getNodeValue();
                        String docCount = node.getTextContent();

                        rangeQueryResultMap.put(query,Integer.parseInt(docCount));      
                }
                System.out.println("rangeQueryResultMap is " + rangeQueryResultMap);
                return rangeQueryResultMap;
                
        }

        /**
         * 
         */
        public long getTotalResults(){
                String resultDocsPath = "/response/result";
                NodeList nodes = null;
                try {
                        nodes = (NodeList) this.xpath.evaluate(resultDocsPath, this.inputSource, XPathConstants.NODESET);
                }
                catch (XPathExpressionException xpee) {
                        return 0;
                }
                
                Node node = nodes.item(0);

                return Long.parseLong(node.getAttributes().getNamedItem("numFound").getNodeValue());
                
        }
                /**
         * 
         * @return
         */
        public long[] getResultEntityIDs() {
                String expression = "/response/result/doc/long";
                
                NodeList nodes = null;
                try {
                        nodes = (NodeList) this.xpath.evaluate(expression, this.inputSource,
                                        XPathConstants.NODESET);
                } 
                catch(XPathExpressionException xpee) {
                        return null;
                }
                
                if(nodes.getLength() == 0) {
                        return null;
                }
                
                long[] values = new long[nodes.getLength()];
                for(int i=0; i<nodes.getLength(); i++) {
                        Node node = nodes.item(i);
                        String value = node.getTextContent();
                        values[i] = Long.parseLong(value);
                }
                
                return values;
        }
        
        /**
         * 
         * @return
         */
        public String[] getResultCategoryNames() {
                String expression = "/response/lst/lst[@name = 'facet_fields']/";
                expression += "lst[@name = 'Category']/int/@name";
                
                NodeList nodes = null;
                try {
                        nodes = (NodeList) this.xpath.evaluate(expression, 
                                this.inputSource, XPathConstants.NODESET);
                }
                catch (XPathExpressionException xpee) {
                        return null;
                }
                
                if(nodes.getLength() == 0) {
                        return null;
                }
                
                String[] values = new String[nodes.getLength()];
                for(int i=0; i<nodes.getLength(); i++) {
                        Node node = nodes.item(i);
                        values[i] = node.getTextContent();
                }
                
                return values;
        }
        
        /**
         * 
         * @return
         */
        public int[] getResultCategoryCounts() {
                String expression = "/response/lst/lst[@name = 'facet_fields']/";
                expression += "lst[@name = 'Category']/int";
                
                NodeList nodes = null;
                try {
                        nodes = (NodeList) this.xpath.evaluate(expression, 
                                this.inputSource, XPathConstants.NODESET);
                }
                catch (XPathExpressionException xpee) {
                        return null;
                }
                
                if(nodes.getLength() == 0) {
                        return null;
                }
                
                int[] values = new int[nodes.getLength()];
                for(int i=0; i<nodes.getLength(); i++) {
                        Node node = nodes.item(i);
                        values[i] = Integer.parseInt(node.getTextContent());
                }
                
                return values;
        }
        
        /**
         * 
         * @return
         */
        public String[]  getResultEntityNames() {
                String expression = "/response/result/doc/str";
                
                NodeList nodes = null;
                try {
                        nodes = (NodeList) this.xpath.evaluate(expression, this.inputSource,
                                        XPathConstants.NODESET);
                } 
                catch(XPathExpressionException xpee) {
                        return null;
                }
                
                if(nodes.getLength() == 0) {
                        return null;
                }
                
                String[] values = new String[nodes.getLength()];
                for(int i=0; i<nodes.getLength(); i++) {
                        Node node = nodes.item(i);
                        String value = node.getTextContent();
                        values[i] = value;
                }
                
                return values;
        }

        /**
         * 
         * @param facetDefinitionID
         * @return
         */
        public String[] getFacetValues(String facetDefinitionID) {
                String expression = "/response/lst/lst[@name = 'facet_fields']/";
                expression += "lst[@name = '"+ facetDefinitionID +"']/int/@name";
                
                NodeList nodes = null;
                try {
                        nodes = (NodeList) this.xpath.evaluate(expression, 
                                this.inputSource, XPathConstants.NODESET);
                }
                catch (XPathExpressionException xpee) {
                        return null;
                }
                
                if(nodes.getLength() == 0) {
                        return null;
                }
                
                String[] values = new String[nodes.getLength()];
                for(int i=0; i<nodes.getLength(); i++) {
                        Node node = nodes.item(i);
                        values[i] = node.getTextContent();
                }
                
                return values;
        }
        
        /**
         * 
         * @param facetDefinitionID
         * @return
         */
        public String[] getFacetCounts(String facetDefinitionID) {
                String expression = "/response/lst/lst[@name = 'facet_fields']/";
                expression += "lst[@name = '" + facetDefinitionID + "']/int";
                
                NodeList nodes = null;
                try {
                        nodes = (NodeList) this.xpath.evaluate(expression, 
                                this.inputSource, XPathConstants.NODESET);
                }
                catch (XPathExpressionException xpee) {
                        return null;
                }
                
                if(nodes.getLength() == 0) {
                        return null;
                }
                
                String[] values = new String[nodes.getLength()];
                for(int i=0; i<nodes.getLength(); i++) {
                        Node node = nodes.item(i);
                        values[i] = node.getTextContent();
//                      log.info("Facets Counts  " + values[i]);
                }
                
                return values;
        }

        public static void main(String[] args){
                /*
        // Hard coded for now
        String[] facetDefIDs = new String[] {"F_50001", "F_50002", "F_50003", "F_50004", "F_50005", "F_50006", "F_50007", "F_50008", "F_50009"};

        // Hard-coded for now
        String[] facetLabels = new String[] {
                "Brand", "Price","Form Factor", "Carry In Pocket", "Cellular Technologies", 
                "Data Connectivity", "Camera Resolution", "Built-in Memory", 
                "Talk time"
        };

                 */
        String[] facetDefIDs = new String[] {"Category","F_50002","F_50001",  "F_50006", "F_50007" };
        
        String[] fqrys = {};
                SolrSearchService search = new SolrSearchService("nokia", fqrys, facetDefIDs, 0 , 20, null, null, 10000, null);
        
        search.getFacetMap();
        
        search.getResultMap();
        search.getRangeQueryResultMap();
        search.getPriceStatsMap();
        search.getTotalResults();
        for (int i=0; i<facetDefIDs.length; i++) {
                search.getFacetCounts(facetDefIDs[i]);
                search.getFacetValues(facetDefIDs[i]);
        }
        
        }
}