Subversion Repositories SmartDukaan

Rev

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