Subversion Repositories SmartDukaan

Rev

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