Subversion Repositories SmartDukaan

Rev

Rev 5873 | Rev 5943 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
317 ashish 1
/**
2
 * 
3
 */
4
package in.shop2020.serving.services;
5
 
6
 
1698 chandransh 7
import in.shop2020.config.ConfigException;
8
import in.shop2020.thrift.clients.config.ConfigClient;
2070 rajveer 9
import in.shop2020.utils.CategoryManager;
1698 chandransh 10
 
354 rajveer 11
import java.util.Arrays;
5729 amit.gupta 12
import java.util.Collections;
354 rajveer 13
import java.util.HashMap;
5729 amit.gupta 14
import java.util.Iterator;
15
import java.util.LinkedHashMap;
790 vikas 16
import java.util.LinkedList;
17
import java.util.List;
5729 amit.gupta 18
import java.util.Map;
354 rajveer 19
import java.util.TreeMap;
20
 
21
 
317 ashish 22
import javax.xml.xpath.XPath;
23
import javax.xml.xpath.XPathConstants;
24
import javax.xml.xpath.XPathExpressionException;
25
import javax.xml.xpath.XPathFactory;
26
 
832 rajveer 27
import org.apache.log4j.Logger;
317 ashish 28
import org.w3c.dom.Node;
29
import org.w3c.dom.NodeList;
30
import org.xml.sax.InputSource;
31
 
354 rajveer 32
 
317 ashish 33
/**
545 rajveer 34
 * @author rajveer
317 ashish 35
 *
36
 */
37
public class SolrSearchService {
38
	/**
39
	 * 
40
	 */
2147 chandransh 41
	private static Logger log = Logger.getLogger(Class.class);
545 rajveer 42
 
43
	/**
44
	 * 
45
	 */
1698 chandransh 46
	public static final String SOLR_URL;
317 ashish 47
 
5729 amit.gupta 48
	private static final Map<String, List<String>> SORTED_FACET_VALUE_MAP = Collections.unmodifiableMap(
49
			new HashMap<String, List<String>>(){
50
				/**
51
				 * 
52
				 */
53
				private static final long serialVersionUID = 1L;
54
 
55
				{
56
					put("F_50007", Arrays.asList("Upto 2 Mpx", "2 - 5 Mpx", "5 - 10 Mpx", "Above 10 Mpx"));
5873 amit.gupta 57
					put("F_50024", Arrays.asList("Upto 10 Mpx", "10 - 12 Mpx", "12 - 15 Mpx", "Above 10 Mpx", "15 - 18 Mpx", "Above 18 Mpx"));
58
					put("F_50025", Arrays.asList("Upto 4x", "4 - 6x", "6 - 10x", "10 - 14x", "14 - 18x", "Above 18x"));
59
					put("F_50026", Arrays.asList("Below 2 in.", "2 to 3 in.", "3 to 5 in.", "Above 5 in."));
5941 amit.gupta 60
					put("F_50027", Arrays.asList("Upto 10 Mpx", "10 - 15 Mpx", "15 - 20 Mpx", "Above 20 Mpx"));
5729 amit.gupta 61
				}
62
		});
1698 chandransh 63
	static {
64
		String solr_url = null;
65
		try {
66
			solr_url = ConfigClient.getClient().get("solr_url");
67
		}catch(ConfigException cex){
2949 chandransh 68
		    log.error("Unable to get the solr URL from the config server. Setting the default value.", cex);
1698 chandransh 69
			solr_url = "http://localhost:8983/solr/select/";
70
		}
71
		SOLR_URL = solr_url;
72
	}
73
 
317 ashish 74
	/**
75
	 * 
76
	 */
77
	private XPath xpath;
78
 
79
	/**
80
	 * 
81
	 */
82
	private InputSource inputSource;
83
 
5729 amit.gupta 84
	Map<String,Map<String,Integer>> facetMap;
354 rajveer 85
 
790 vikas 86
	List<String> resultMap;
545 rajveer 87
 
88
	long numberOfResults=0;
3561 rajveer 89
 
90
	String priceFacetName = "F_50002";
91
 
317 ashish 92
	/**
93
	 * 
94
	 * @param query
95
	 * @param facetDefinitionIDs
96
	 */
3561 rajveer 97
	public SolrSearchService(String query, String[] facetqueries, String[] facetDefinitionIDs, long start, long rows,  Double minPrice, Double maxPrice, long categoryId, String sortOrder, long sourceId) {
354 rajveer 98
 
3561 rajveer 99
		if(sourceId != -1){
100
			priceFacetName = priceFacetName + "_" + sourceId;
101
		}
102
 
317 ashish 103
		this.xpath = XPathFactory.newInstance().newXPath();
545 rajveer 104
 
2606 rajveer 105
		query = query.trim().replaceAll("\\s+", " ");
545 rajveer 106
    	log.info("query=" + query);
107
 
317 ashish 108
		String uri = SOLR_URL + "?wt=xml&q=" + query;
109
 
3561 rajveer 110
		uri += "&stats=on&stats.field=" + priceFacetName;
545 rajveer 111
 
112
 
113
		if(minPrice != null || maxPrice != null){
114
			String minString = "0";
115
			String maxString = "*";  
116
			if(minPrice != null){
117
				minString = minPrice.toString();
118
			}
119
			if(maxPrice != null){
120
				maxString = maxPrice.toString();
121
			}
3561 rajveer 122
			uri += "&fq=" + priceFacetName + ":["+  minString + " " + maxString + "]";
354 rajveer 123
		}
124
 
569 rajveer 125
		if(categoryId != 10000){
126
			uri += "&fq=F_50010:\"" + CategoryManager.getCategoryManager().getCategoryLabel(categoryId) + "\"";
127
		}
354 rajveer 128
 
569 rajveer 129
		if(sortOrder != null){
3561 rajveer 130
			//replace the price facet name, so that it can pick price for the source.
131
			sortOrder = sortOrder.replace("F_50002", priceFacetName);
569 rajveer 132
			uri += "&sort=" + sortOrder;
133
		}
545 rajveer 134
 
317 ashish 135
		if(facetqueries != null) {
136
			for(int i=0; i<facetqueries.length; i++) {
3262 rajveer 137
				if(facetqueries[i].contains(" ") && !(facetqueries[i].contains("F_50002") || facetqueries[i].contains(" OR "))){
536 rajveer 138
					String[] tokens = facetqueries[i].split(":");
545 rajveer 139
					uri += "&fq=" + tokens[0] + ":\"" + tokens[1] + "\"";
536 rajveer 140
				}else{
141
					uri += "&fq=" + facetqueries[i] + "";
142
				}
317 ashish 143
			}
144
		}
545 rajveer 145
		uri += "&fl=ID,Name&facet=true&start=" + start + "&rows=" + rows;
2435 rajveer 146
		if(facetDefinitionIDs != null){
147
			for(int i=0; i<facetDefinitionIDs.length; i++) {
148
				uri += "&facet.field=" + facetDefinitionIDs[i];
149
			}
317 ashish 150
		}
3262 rajveer 151
		log.info("uri=" + uri);
317 ashish 152
 
153
		this.inputSource = new InputSource(uri);
517 rajveer 154
 
545 rajveer 155
		this.facetMap = getFacetMap();
354 rajveer 156
	}
157
 
5729 amit.gupta 158
	public Map<String,Map<String,Integer>> removeUnwantedFacets(Map<String,Map<String,Integer>> facetMap, long numberOfResults){
159
		Map<String,Map<String,Integer>> tempFacets = new TreeMap<String, Map<String,Integer>>(); 
354 rajveer 160
		for(String facet : facetMap.keySet()){
545 rajveer 161
			if(facetMap.get(facet).size() > 1){
5729 amit.gupta 162
				Map<String,Integer> tempMap = new LinkedHashMap<String, Integer>();
545 rajveer 163
 
354 rajveer 164
				for(String facetValueName : facetMap.get(facet).keySet()){
545 rajveer 165
					if(facetMap.get(facet).get(facetValueName) != 0 && facetMap.get(facet).get(facetValueName) != numberOfResults){
166
						tempMap.put(facetValueName, facetMap.get(facet).get(facetValueName));
354 rajveer 167
					}
168
				}
545 rajveer 169
				if(!tempMap.isEmpty()){
170
					tempFacets.put(facet, tempMap);
354 rajveer 171
				}
545 rajveer 172
			}	
354 rajveer 173
		}
550 rajveer 174
		if(tempFacets.containsKey("F_50010")){
175
			tempFacets.remove("F_50011");
176
		}
354 rajveer 177
 
178
		return tempFacets;
179
	}
180
 
5729 amit.gupta 181
	public Map<String,Integer> getFacetDetails(String facetName){
2606 rajveer 182
		if(facetMap != null){
183
			return facetMap.get(facetName);
184
		}else{
185
			return null;
186
		}
354 rajveer 187
	}
188
 
5729 amit.gupta 189
	public Map<String,Map<String,Integer>> getFacetMap() {
190
		facetMap = new TreeMap<String,Map<String,Integer>>();
354 rajveer 191
 
192
		String facetNamePath = "/response/lst/lst[@name = 'facet_fields']/lst";
545 rajveer 193
 
354 rajveer 194
		NodeList nodes = null;
195
		try {
196
			nodes = (NodeList) this.xpath.evaluate(facetNamePath, this.inputSource, XPathConstants.NODESET);
197
		}
198
		catch (XPathExpressionException xpee) {
199
			return null;
200
		}
201
 
202
		if(nodes.getLength() == 0) {
203
			return null;
204
		}
205
 
206
		NodeList subNodes = null;
207
 
208
		for(int i=0; i<nodes.getLength(); i++) {
209
			Node node = nodes.item(i);
2946 chandransh 210
			String facetName = node.getAttributes().getNamedItem("name").getNodeValue();
354 rajveer 211
			subNodes = node.getChildNodes();
5729 amit.gupta 212
			Map<String,Integer> facetValueCountMap = new LinkedHashMap<String,Integer>();
354 rajveer 213
			for(int j=0; j<subNodes.getLength(); j++) {
214
				Node subNode = subNodes.item(j);
215
				if(Integer.parseInt(subNode.getTextContent())==0)
216
						continue;
217
				facetValueCountMap.put(subNode.getAttributes().getNamedItem("name").getNodeValue(), Integer.parseInt(subNode.getTextContent()));
218
			}
5729 amit.gupta 219
			if(SORTED_FACET_VALUE_MAP.containsKey(facetName)){
220
				List<String> orderedValues = SORTED_FACET_VALUE_MAP.get(facetName);
221
				Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
222
			    for (Iterator<String> it = orderedValues.iterator(); it.hasNext();) {
223
			    	String val = it.next();
224
			        if(facetValueCountMap.containsKey(val)) {
225
			        	sortedMap.put(val, facetValueCountMap.get(val));
226
			        }
227
			    }
228
			    facetMap.put(facetName, sortedMap);
229
			} else {
230
				facetMap.put(facetName, facetValueCountMap);
354 rajveer 231
			}
5729 amit.gupta 232
		}
545 rajveer 233
		this.numberOfResults  = this.getTotalResults();
517 rajveer 234
 
354 rajveer 235
		facetMap = removeUnwantedFacets(facetMap, numberOfResults);
236
		return facetMap;
5729 amit.gupta 237
	}
354 rajveer 238
 
790 vikas 239
	public List<String> getResultMap() {
240
		resultMap = new LinkedList<String>();
354 rajveer 241
 
242
		String resultDocsPath = "/response/result/doc";
243
 
244
 
245
		NodeList nodes = null;
246
		try {
247
			nodes = (NodeList) this.xpath.evaluate(resultDocsPath, this.inputSource, XPathConstants.NODESET);
248
		}
249
		catch (XPathExpressionException xpee) {
250
			return null;
251
		}
252
 
253
		if(nodes.getLength() == 0) {
254
			return null;
255
		}
256
 
257
		for(int i=0; i<nodes.getLength(); i++) {
258
			Node node = nodes.item(i);
259
			String docID = node.getFirstChild().getTextContent();
790 vikas 260
			resultMap.add(docID);	
354 rajveer 261
 		}
262
		return resultMap;
263
	}
264
 
265
	public HashMap<String, Double> getPriceStatsMap() {
266
		HashMap<String, Double> priceStatsMap = new HashMap<String, Double>();
267
 
3561 rajveer 268
		String resultDocsPath = "/response/lst[@name = 'stats']/lst[@name = 'stats_fields']/lst[@name = '" + priceFacetName + "']";
354 rajveer 269
 
270
 
271
		NodeList nodes = null;
272
		try {
273
			nodes = (NodeList) this.xpath.evaluate(resultDocsPath, this.inputSource, XPathConstants.NODESET);
274
		}
275
		catch (XPathExpressionException xpee) {
276
			return null;
277
		}
278
 
279
		if(nodes.getLength() == 0) {
280
			return null;
281
		}
282
 
283
		NodeList subNodes = nodes.item(0).getChildNodes();
284
 
285
		for(int i=0; i<subNodes.getLength(); i++) {
286
			Node node = subNodes.item(i);
287
 
288
			String parameter = node.getAttributes().getNamedItem("name").getNodeValue();
289
			String value = node.getTextContent();
290
			priceStatsMap.put(parameter, Double.parseDouble(value));	
291
 		}
292
		return priceStatsMap;
293
	}
294
 
295
	public HashMap<String,Integer> getRangeQueryResultMap() {
296
		HashMap<String, Integer> rangeQueryResultMap = new HashMap<String,Integer>();
297
 
298
		String resultDocsPath = "/response/lst[@name = 'facet_counts']/lst[@name = 'facet_queries']/int";
299
 
300
 
301
		NodeList nodes = null;
302
		try {
303
			nodes = (NodeList) this.xpath.evaluate(resultDocsPath, this.inputSource, XPathConstants.NODESET);
304
		}
305
		catch (XPathExpressionException xpee) {
306
			return null;
307
		}
308
 
309
		if(nodes.getLength() == 0) {
310
			return null;
311
		}
312
 
313
 
314
		for(int i=0; i<nodes.getLength(); i++) {
315
			Node node = nodes.item(i);
316
 
317
			String query = node.getAttributes().getNamedItem("name").getNodeValue();
318
			String docCount = node.getTextContent();
319
 
320
			rangeQueryResultMap.put(query,Integer.parseInt(docCount));	
321
 		}
322
		return rangeQueryResultMap;
323
 
324
	}
325
 
545 rajveer 326
	/**
327
	 * 
328
	 */
329
	public long getTotalResults(){
330
		String resultDocsPath = "/response/result";
331
		NodeList nodes = null;
332
		try {
333
			nodes = (NodeList) this.xpath.evaluate(resultDocsPath, this.inputSource, XPathConstants.NODESET);
334
		}
335
		catch (XPathExpressionException xpee) {
336
			return 0;
337
		}
338
 
339
		Node node = nodes.item(0);
340
 
341
		return Long.parseLong(node.getAttributes().getNamedItem("numFound").getNodeValue());
342
 
343
	}
354 rajveer 344
		/**
317 ashish 345
	 * 
346
	 * @return
347
	 */
348
	public long[] getResultEntityIDs() {
349
		String expression = "/response/result/doc/long";
350
 
351
		NodeList nodes = null;
352
		try {
353
			nodes = (NodeList) this.xpath.evaluate(expression, this.inputSource,
354
					XPathConstants.NODESET);
355
		} 
356
		catch(XPathExpressionException xpee) {
357
			return null;
358
		}
359
 
360
		if(nodes.getLength() == 0) {
361
			return null;
362
		}
363
 
364
		long[] values = new long[nodes.getLength()];
365
		for(int i=0; i<nodes.getLength(); i++) {
366
			Node node = nodes.item(i);
367
			String value = node.getTextContent();
368
			values[i] = Long.parseLong(value);
369
 		}
370
 
371
		return values;
372
	}
373
 
374
	/**
375
	 * 
376
	 * @return
377
	 */
378
	public String[] getResultCategoryNames() {
379
		String expression = "/response/lst/lst[@name = 'facet_fields']/";
380
		expression += "lst[@name = 'Category']/int/@name";
381
 
382
		NodeList nodes = null;
383
		try {
384
			nodes = (NodeList) this.xpath.evaluate(expression, 
385
				this.inputSource, XPathConstants.NODESET);
386
		}
387
		catch (XPathExpressionException xpee) {
388
			return null;
389
		}
390
 
391
		if(nodes.getLength() == 0) {
392
			return null;
393
		}
394
 
395
		String[] values = new String[nodes.getLength()];
396
		for(int i=0; i<nodes.getLength(); i++) {
397
			Node node = nodes.item(i);
398
			values[i] = node.getTextContent();
399
 		}
400
 
401
		return values;
402
	}
403
 
404
	/**
405
	 * 
406
	 * @return
407
	 */
408
	public int[] getResultCategoryCounts() {
409
		String expression = "/response/lst/lst[@name = 'facet_fields']/";
410
		expression += "lst[@name = 'Category']/int";
411
 
412
		NodeList nodes = null;
413
		try {
414
			nodes = (NodeList) this.xpath.evaluate(expression, 
415
				this.inputSource, XPathConstants.NODESET);
416
		}
417
		catch (XPathExpressionException xpee) {
418
			return null;
419
		}
420
 
421
		if(nodes.getLength() == 0) {
422
			return null;
423
		}
424
 
425
		int[] values = new int[nodes.getLength()];
426
		for(int i=0; i<nodes.getLength(); i++) {
427
			Node node = nodes.item(i);
428
			values[i] = Integer.parseInt(node.getTextContent());
429
 		}
430
 
431
		return values;
432
	}
433
 
434
	/**
435
	 * 
436
	 * @return
437
	 */
438
	public String[]  getResultEntityNames() {
439
		String expression = "/response/result/doc/str";
440
 
441
		NodeList nodes = null;
442
		try {
443
			nodes = (NodeList) this.xpath.evaluate(expression, this.inputSource,
444
					XPathConstants.NODESET);
445
		} 
446
		catch(XPathExpressionException xpee) {
447
			return null;
448
		}
449
 
450
		if(nodes.getLength() == 0) {
451
			return null;
452
		}
453
 
454
		String[] values = new String[nodes.getLength()];
455
		for(int i=0; i<nodes.getLength(); i++) {
456
			Node node = nodes.item(i);
457
			String value = node.getTextContent();
458
			values[i] = value;
459
 		}
460
 
461
		return values;
462
	}
463
 
464
	/**
465
	 * 
466
	 * @param facetDefinitionID
467
	 * @return
468
	 */
354 rajveer 469
	public String[] getFacetValues(String facetDefinitionID) {
317 ashish 470
		String expression = "/response/lst/lst[@name = 'facet_fields']/";
354 rajveer 471
		expression += "lst[@name = '"+ facetDefinitionID +"']/int/@name";
317 ashish 472
 
473
		NodeList nodes = null;
474
		try {
475
			nodes = (NodeList) this.xpath.evaluate(expression, 
476
				this.inputSource, XPathConstants.NODESET);
477
		}
478
		catch (XPathExpressionException xpee) {
479
			return null;
480
		}
481
 
482
		if(nodes.getLength() == 0) {
483
			return null;
484
		}
485
 
486
		String[] values = new String[nodes.getLength()];
487
		for(int i=0; i<nodes.getLength(); i++) {
488
			Node node = nodes.item(i);
489
			values[i] = node.getTextContent();
545 rajveer 490
		}
317 ashish 491
 
492
		return values;
493
	}
494
 
495
	/**
496
	 * 
497
	 * @param facetDefinitionID
498
	 * @return
499
	 */
354 rajveer 500
	public String[] getFacetCounts(String facetDefinitionID) {
317 ashish 501
		String expression = "/response/lst/lst[@name = 'facet_fields']/";
354 rajveer 502
		expression += "lst[@name = '" + facetDefinitionID + "']/int";
317 ashish 503
 
504
		NodeList nodes = null;
505
		try {
506
			nodes = (NodeList) this.xpath.evaluate(expression, 
507
				this.inputSource, XPathConstants.NODESET);
508
		}
509
		catch (XPathExpressionException xpee) {
510
			return null;
511
		}
512
 
513
		if(nodes.getLength() == 0) {
514
			return null;
515
		}
516
 
517
		String[] values = new String[nodes.getLength()];
518
		for(int i=0; i<nodes.getLength(); i++) {
519
			Node node = nodes.item(i);
520
			values[i] = node.getTextContent();
521
 		}
522
 
523
		return values;
524
	}
545 rajveer 525
 
526
	public static void main(String[] args){
527
		/*
528
    	// Hard coded for now
529
    	String[] facetDefIDs = new String[] {"F_50001", "F_50002", "F_50003", "F_50004", "F_50005", "F_50006", "F_50007", "F_50008", "F_50009"};
530
 
531
    	// Hard-coded for now
532
    	String[] facetLabels = new String[] {
533
	    	"Brand", "Price","Form Factor", "Carry In Pocket", "Cellular Technologies", 
534
	    	"Data Connectivity", "Camera Resolution", "Built-in Memory", 
535
	    	"Talk time"
536
    	};
537
 
538
		 */
539
    	String[] facetDefIDs = new String[] {"Category","F_50002","F_50001",  "F_50006", "F_50007" };
2147 chandransh 540
    	//String[] facetLabels = new String[] {"Category","Price", "Brand", "Data Connectivity", "Camera Resolution"	};
545 rajveer 541
 
542
 
543
    	String[] fqrys = {};
3561 rajveer 544
		SolrSearchService search = new SolrSearchService("nokia", fqrys, facetDefIDs, 0 , 20, null, null, 10000, null, -1);
545 rajveer 545
 
546
    	long[] entityIDs = search.getResultEntityIDs();
547
    	log.info("entityIDs=" + Arrays.toString(entityIDs));
548
 
549
    	String[] entityNames = search.getResultEntityNames();
550
    	log.info("entityNames=" + Arrays.toString(entityNames));
551
    	search.getFacetMap();
552
 
553
    	search.getResultMap();
554
    	search.getRangeQueryResultMap();
555
    	search.getPriceStatsMap();
556
    	search.getTotalResults();
557
       	for (int i=0; i<facetDefIDs.length; i++) {
558
       		search.getFacetCounts(facetDefIDs[i]);
559
       		search.getFacetValues(facetDefIDs[i]);
560
       	}
561
 
562
	}
317 ashish 563
}