Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
7226 anupam.sin 1
/**
2
 * 
3
 */
4
package in.shop2020.serving.service;
5
 
6
 
7
import in.shop2020.config.ConfigException;
8
import in.shop2020.serving.controllers.SearchController;
9
import in.shop2020.serving.utils.Utils;
10
import in.shop2020.thrift.clients.config.ConfigClient;
11
 
12
import java.util.ArrayList;
13
import java.util.Arrays;
14
import java.util.Collections;
15
import java.util.HashMap;
16
import java.util.HashSet;
17
import java.util.Iterator;
18
import java.util.LinkedHashMap;
19
import java.util.LinkedList;
20
import java.util.List;
21
import java.util.Map;
22
import java.util.Set;
23
import java.util.TreeMap;
24
import java.util.regex.Matcher;
25
import java.util.regex.Pattern;
26
 
27
import javax.xml.xpath.XPath;
28
import javax.xml.xpath.XPathConstants;
29
import javax.xml.xpath.XPathExpressionException;
30
import javax.xml.xpath.XPathFactory;
31
 
32
import org.apache.commons.collections.ListUtils;
33
import org.apache.log4j.Logger;
34
import org.w3c.dom.Node;
35
import org.w3c.dom.NodeList;
36
import org.xml.sax.InputSource;
37
 
38
 
39
/**
40
 * @author rajveer
41
 *
42
 */
43
public class SearchService {
44
    /**
45
     * 
46
     */
47
    private static Logger log = Logger.getLogger(Class.class);
48
    private HashMap<String, Double> dynamicPriceMap = null;
49
 
50
    /**
51
     * 
52
     */
53
    public static final String SOLR_URL;
54
 
55
    private static final Pattern FACET_PATTERN = Pattern.compile("(?=(F_\\d{5}))");
56
 
57
    private static final Map<String, List<String>> SORTED_FACET_VALUE_MAP = Collections.unmodifiableMap(
58
            new HashMap<String, List<String>>(){
59
                /**
60
                 * 
61
                 */
62
                private static final long serialVersionUID = 1L;
63
                {
64
                    put("F_50007", Arrays.asList("Upto 2 Mpx", "2 - 5 Mpx", "5 - 10 Mpx", "10 Mpx and above"));
65
                    put("F_50024", Arrays.asList("Upto 10 Mpx", "10 - 12 Mpx", "12 - 15 Mpx", "15 - 18 Mpx", "18 Mpx and above"));
66
                    put("F_50025", Arrays.asList("Upto 4x", "4 - 6x", "6 - 10x", "10 - 14x", "14 - 18x", "18x and above"));
67
                    put("F_50026", Arrays.asList("Below 2 in.", "2 to 2.9 in.", "3 to 3.9 in.", "4 in. and above"));
68
                    put("F_50032", Arrays.asList("Below 3 in.", "3 to 3.9 in.", "4 to 4.9 in.", "5 in. and above"));
69
                    put("F_50027", Arrays.asList("Upto 10 Mpx", "10 - 15 Mpx", "15 - 20 Mpx", "20 Mpx and above"));
70
                }
71
        });
72
    public static final Map<String, List<String>> CATEGORY_FACET_MAP = Collections.unmodifiableMap(
73
            new HashMap<String, List<String>>(){
74
                /**
75
                 * 
76
                 */
77
                private static final long serialVersionUID = 1L;
78
                //Data Connectivity, Camera Resolution,Operating System,Screen Size
79
                List<String> mobileFacets = Arrays.asList("F_50006", "F_50007", "F_50031", "F_50032");
80
                //Camera Resolution,Operating System,Screen Size
81
                List<String> tabletFacets = Arrays.asList("F_50036", "F_50035", "F_50034");
82
                //Operating System, Processor, Storage, RAM, Screen Size
83
                List<String> laptopFacets = Arrays.asList("F_50013", "F_50014", "F_50015","F_50017", "F_50033");
84
                //Resolution, Optical Zoon, Display Size
85
                List<String> compactCameras = Arrays.asList("F_50024", "F_50025", "F_50026");
86
                //Display Size
87
                List<String> dslrCameras = Arrays.asList("F_50026");
88
                //Capacity, Class
89
                List<String> memoryCards = Arrays.asList("F_50018", "F_50019");
90
                //Capacity
91
                List<String> penDrives = Arrays.asList("F_50020");
92
                //Capacity, Type, Interface
93
                List<String> externalHardDisks = Arrays.asList("F_50021", "F_50022", "F_50023");
94
                {                   
95
                    put(SearchController.getCategoryLabel(10001l), mobileFacets);
12333 amit.gupta 96
                    put(SearchController.getCategoryLabel(10006l), mobileFacets);
7226 anupam.sin 97
                    put(SearchController.getCategoryLabel(10002l), mobileFacets);
98
                    put(SearchController.getCategoryLabel(10003l), mobileFacets);
99
                    put(SearchController.getCategoryLabel(10004l), mobileFacets);
100
                    put(SearchController.getCategoryLabel(10005l), mobileFacets);
12333 amit.gupta 101
                    put(SearchController.getCategoryLabel(10006l), mobileFacets);
7226 anupam.sin 102
                    put(SearchController.getCategoryLabel(10009l), tabletFacets);
103
                    put(SearchController.getCategoryLabel(10010l), tabletFacets);
104
                    put(SearchController.getCategoryLabel(10013l), memoryCards);
105
                    put(SearchController.getCategoryLabel(10017l), penDrives);
106
                    put(SearchController.getCategoryLabel(10049l), laptopFacets);
107
                    put(SearchController.getCategoryLabel(10050l), laptopFacets);
108
                    put(SearchController.getCategoryLabel(10073l), externalHardDisks);
109
                    put(SearchController.getCategoryLabel(11002l), compactCameras);
110
                    put(SearchController.getCategoryLabel(11003l), dslrCameras);
111
                }
112
            });
113
    static {
114
        String solr_url = null;
115
        try {
116
            solr_url = ConfigClient.getClient().get("solr_url");
117
        }catch(ConfigException cex){
118
            log.error("Unable to get the solr URL from the config server. Setting the default value.", cex);
119
            solr_url = "http://localhost:8983/solr/select/";
120
        }
121
        SOLR_URL = solr_url;
122
    }
123
 
124
    /**
125
     * 
126
     */
127
    private XPath xpath;
128
 
129
    /**
130
     * 
131
     */
132
    private InputSource inputSource;
133
 
134
    Map<String,Map<String,Integer>> facetMap;
135
 
136
    private String  query;
137
 
138
    List<String> resultMap;
139
 
140
    long numberOfResults=0;
141
 
142
    String priceFacetName = "F_50002";
143
 
144
    List<String> filtrableFacets;
145
 
146
    /**
147
     * 
148
     * @param query
149
     * @param facetDefinitionIDs
150
     */
151
    public SearchService(String query, String[] facetqueries, long start, long rows,  Double minPrice, Double maxPrice, String sortOrder, long sourceId) {
152
        this.query = query;
153
 
154
        List<String> facetsQueried = new ArrayList<String>();
155
        if(sourceId != -1){
156
            priceFacetName = priceFacetName + "_" + sourceId;
157
        }
158
 
159
        setFilterableFacets(facetqueries);
160
 
161
 
162
        this.xpath = XPathFactory.newInstance().newXPath();
163
 
164
        query = query.trim().replaceAll("\\s+", " ");
165
        log.info("query=" + query);
166
 
167
        String uri = SOLR_URL + "?wt=xml&q=" + query;
168
 
169
        uri += "&stats=on&stats.field=" + priceFacetName;
170
 
171
        if(sortOrder != null){
172
            //replace the price facet name, so that it can pick price for the source.
173
            sortOrder = sortOrder.replace("F_50002", priceFacetName);
174
            uri += "&sort=" + sortOrder;
175
        }
176
 
177
        if(facetqueries != null) {
178
            //sorting will guarantee all similar facets together so that we can assume or between all similar items without fail.
179
            Arrays.sort(facetqueries);
180
            String fq="";
181
            for(int i=0; i<facetqueries.length; i++) {
182
                String[] tokens = facetqueries[i].split(":");
183
                if(facetsQueried.contains(tokens[0])) {
184
                    uri += " OR ";
185
                    if(facetqueries[i].contains(" ")){
186
                        uri +=  "\"" + tokens[1] + "\"";
187
                    }else{
188
                        uri += facetqueries[i];
189
                    }
190
 
191
                } else {
192
                    fq = "{!tag=dt" + facetsQueried.size() + "}";
193
                    facetsQueried.add(tokens[0]);
194
                    if(facetqueries[i].contains(" ") && !(facetqueries[i].contains(" OR "))){
195
                        fq +=  tokens[0] + ":\"" + tokens[1] + "\"";
196
                    }else{
197
                        fq += facetqueries[i] + "";
198
                    }
199
                    uri += "&fq=" + fq;
200
                }
201
            }
202
        }
203
        String minString = "0";
204
        String maxString = "*";  
205
        if(minPrice != null || maxPrice != null){
206
            try {
207
                dynamicPriceMap = getPriceStatsMap(new InputSource(uri)); 
208
            } catch (Exception e){
209
                e.printStackTrace();
210
            }
211
            if(minPrice != null){
212
                minString = minPrice.toString();
213
            }
214
            if(maxPrice != null){
215
                maxString = maxPrice.toString();
216
            }
217
        }
218
        uri += "&fq=" + priceFacetName + ":["+  minString + " " + maxString + "]";
219
        uri += "&fl=ID,Name&facet=true&start=" + start + "&rows=" + rows + "&facet.mincount=1";
220
        for(String facetDefinitionID : filtrableFacets) {
221
                if(facetsQueried.contains(facetDefinitionID)){
222
                    uri += "&facet.field={!ex=dt" + facetsQueried.indexOf(facetDefinitionID)+ "}"+ facetDefinitionID; 
223
                } else {
224
                    uri += "&facet.field=" + facetDefinitionID;
225
                }
226
        }
227
        log.info("uri=" + uri);
228
 
229
        this.inputSource = new InputSource(uri);
230
 
231
        this.facetMap = getFacetMap();
232
    }
233
 
234
    @SuppressWarnings("unchecked")
235
    private void setFilterableFacets(String[] facetqueries) {
236
        List<String> queriedFacets = getAllMatches(this.query);
237
        if(facetqueries != null) {
238
            String facetString = Arrays.toString(facetqueries);
239
            List<String> filteredFacets = getAllMatches(facetString);
240
            if(filteredFacets.contains("F_50011")){
241
                for(String facetQuery : facetqueries) {
242
                    if(facetQuery.contains("F_50011")){
243
                        String facetVal = facetQuery.split(":")[1];
244
                        if(CATEGORY_FACET_MAP.containsKey(facetVal)){
245
                            this.filtrableFacets = ListUtils.sum(Utils.rootfacetDefIDs, CATEGORY_FACET_MAP.get(facetVal));
246
                            return;
247
                        } else {
248
                            break;
249
                        }
250
                    }
251
                }
252
            }
253
            if(filteredFacets.contains("F_50010")){
254
                for(String facetQuery : facetqueries) {
255
                    if(facetQuery.contains("F_50010")){
256
                        String facetVal = facetQuery.split(":")[1];
257
                        if(CATEGORY_FACET_MAP.containsKey(facetVal)){
258
                            this.filtrableFacets = ListUtils.sum(Utils.rootfacetDefIDs, CATEGORY_FACET_MAP.get(facetVal));
259
                            return;
260
                        } else {
261
                            break;
262
                        }
263
                    }
264
                }
265
            }
266
        }
267
        if(queriedFacets.contains("F_50011")) {
268
            String facetVal = this.query.split("F_50011:")[1];
269
            if (facetVal.contains(" OR ")) {
270
                this.filtrableFacets = Utils.rootfacetDefIDs;
271
                return;
272
            } else if(CATEGORY_FACET_MAP.containsKey(facetVal)){
273
                facetVal = facetVal.split("&")[0].replaceAll("[\"()]", "");
274
                if(CATEGORY_FACET_MAP.containsKey(facetVal)){
275
                    this.filtrableFacets = ListUtils.sum(Utils.rootfacetDefIDs, CATEGORY_FACET_MAP.get(facetVal));
276
                    return;
277
                }
278
            } 
279
        }
280
        if(queriedFacets.contains("F_50010")){
281
            String facetVal = this.query.split("F_50010:")[1];
282
            if (facetVal.contains(" OR ")) {
283
                this.filtrableFacets = Utils.rootfacetDefIDs;
284
                return;
285
            } else if(CATEGORY_FACET_MAP.containsKey(facetVal)){
286
                facetVal = facetVal.split("&")[0].replaceAll("[\"()]", "");
287
                if(CATEGORY_FACET_MAP.containsKey(facetVal)){
288
                    this.filtrableFacets = ListUtils.sum(Utils.rootfacetDefIDs, CATEGORY_FACET_MAP.get(facetVal));
289
                    return;
290
                }
291
            }
292
        }
293
        this.filtrableFacets = Utils.rootfacetDefIDs;
294
    }
295
 
296
    public List<String> getFilterableFacets() {
297
        return this.filtrableFacets; 
298
    }
299
 
300
    public Map<String,Map<String,Integer>> removeUnwantedFacets(Map<String,Map<String,Integer>> facetMap, long numberOfResults){
301
 
302
        Set<String> facetsInQuery = new HashSet<String>(getAllMatches(this.query));
303
        Map<String,Map<String,Integer>> tempFacets = new TreeMap<String, Map<String,Integer>>(); 
304
        for(String facet : facetMap.keySet()){
305
            if(facetMap.get(facet).size() > 0 && !facetsInQuery.contains(facet)){
306
                Map<String,Integer> tempMap = new LinkedHashMap<String, Integer>();
307
 
308
                for(String facetValueName : facetMap.get(facet).keySet()){
309
                    //if(facetMap.get(facet).get(facetValueName) != 0 && facetMap.get(facet).get(facetValueName) != numberOfResults){
310
                        tempMap.put(facetValueName, facetMap.get(facet).get(facetValueName));
311
                    //}
312
                }
313
                if(!tempMap.isEmpty()){
314
                    tempFacets.put(facet, tempMap);
315
                }
316
            }   
317
        }
318
        /*if(tempFacets.containsKey("F_50010")){
319
            tempFacets.remove("F_50011");
320
        }*/
321
 
322
        return tempFacets;
323
    }
324
 
325
    public Map<String,Integer> getFacetDetails(String facetName){
326
        if(facetMap != null){
327
            return facetMap.get(facetName);
328
        }else{
329
            return null;
330
        }
331
    }
332
 
333
    public Map<String,Map<String,Integer>> getFacetMap() {
334
        facetMap = new TreeMap<String,Map<String,Integer>>();
335
 
336
        String facetNamePath = "/response/lst/lst[@name = 'facet_fields']/lst";
337
 
338
        NodeList nodes = null;
339
        try {
340
            nodes = (NodeList) this.xpath.evaluate(facetNamePath, this.inputSource, XPathConstants.NODESET);
341
        }
342
        catch (XPathExpressionException xpee) {
343
            return null;
344
        }
345
 
346
        if(nodes.getLength() == 0) {
347
            return null;
348
        }
349
 
350
        NodeList subNodes = null;
351
 
352
        for(int i=0; i<nodes.getLength(); i++) {
353
            Node node = nodes.item(i);
354
            String facetName = node.getAttributes().getNamedItem("name").getNodeValue();
355
            subNodes = node.getChildNodes();
356
            Map<String,Integer> facetValueCountMap = new LinkedHashMap<String,Integer>();
357
            for(int j=0; j<subNodes.getLength(); j++) {
358
                Node subNode = subNodes.item(j);
359
                facetValueCountMap.put(subNode.getAttributes().getNamedItem("name").getNodeValue(), Integer.parseInt(subNode.getTextContent()));
360
            }
361
            if(SORTED_FACET_VALUE_MAP.containsKey(facetName)){
362
                List<String> orderedValues = SORTED_FACET_VALUE_MAP.get(facetName);
363
                Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
364
                for (Iterator<String> it = orderedValues.iterator(); it.hasNext();) {
365
                    String val = it.next();
366
                    if(facetValueCountMap.containsKey(val)) {
367
                        sortedMap.put(val, facetValueCountMap.get(val));
368
                    }
369
                }
370
                facetMap.put(facetName, sortedMap);
371
            } else {
372
                facetMap.put(facetName, facetValueCountMap);
373
            }
374
        }
375
        this.numberOfResults  = this.getTotalResults();
376
 
377
        facetMap = removeUnwantedFacets(facetMap, numberOfResults);
378
        return facetMap;
379
    }
380
 
381
    public List<String> getResultMap() {
382
        resultMap = new LinkedList<String>();
383
 
384
        String resultDocsPath = "/response/result/doc";
385
 
386
 
387
        NodeList nodes = null;
388
        try {
389
            nodes = (NodeList) this.xpath.evaluate(resultDocsPath, this.inputSource, XPathConstants.NODESET);
390
        }
391
        catch (XPathExpressionException xpee) {
392
            return null;
393
        }
394
 
395
        if(nodes.getLength() == 0) {
396
            return null;
397
        }
398
 
399
        for(int i=0; i<nodes.getLength(); i++) {
400
            Node node = nodes.item(i);
401
            String docID = node.getFirstChild().getTextContent();
402
            resultMap.add(docID);   
403
        }
404
        return resultMap;
405
    }
406
 
407
    public HashMap<String, Double> getPriceStatsMap() {
408
        return this.getPriceStatsMap(this.inputSource);
409
    }
410
 
411
    public HashMap<String, Double> getPriceStatsMap(InputSource inputSource) {
412
        HashMap<String, Double> priceStatsMap = new HashMap<String, Double>();
413
 
414
        String resultDocsPath = "/response/lst[@name = 'stats']/lst[@name = 'stats_fields']/lst[@name = '" + priceFacetName + "']";
415
 
416
 
417
        NodeList nodes = null;
418
        try {
419
            nodes = (NodeList) this.xpath.evaluate(resultDocsPath, inputSource, XPathConstants.NODESET);
420
        }
421
        catch (XPathExpressionException xpee) {
422
            return null;
423
        }
424
 
425
        if(nodes.getLength() == 0) {
426
            return null;
427
        }
428
 
429
        NodeList subNodes = nodes.item(0).getChildNodes();
430
 
431
        for(int i=0; i<subNodes.getLength(); i++) {
432
            Node node = subNodes.item(i);
433
 
434
            String parameter = node.getAttributes().getNamedItem("name").getNodeValue();
435
            String value = node.getTextContent();
436
            priceStatsMap.put(parameter, Double.parseDouble(value));    
437
        }
438
        return priceStatsMap;
439
    }
440
 
441
    public HashMap<String,Integer> getRangeQueryResultMap() {
442
        HashMap<String, Integer> rangeQueryResultMap = new HashMap<String,Integer>();
443
 
444
        String resultDocsPath = "/response/lst[@name = 'facet_counts']/lst[@name = 'facet_queries']/int";
445
 
446
 
447
        NodeList nodes = null;
448
        try {
449
            nodes = (NodeList) this.xpath.evaluate(resultDocsPath, this.inputSource, XPathConstants.NODESET);
450
        }
451
        catch (XPathExpressionException xpee) {
452
            return null;
453
        }
454
 
455
        if(nodes.getLength() == 0) {
456
            return null;
457
        }
458
 
459
 
460
        for(int i=0; i<nodes.getLength(); i++) {
461
            Node node = nodes.item(i);
462
 
463
            String query = node.getAttributes().getNamedItem("name").getNodeValue();
464
            String docCount = node.getTextContent();
465
 
466
            rangeQueryResultMap.put(query,Integer.parseInt(docCount));  
467
        }
468
        return rangeQueryResultMap;
469
 
470
    }
471
 
472
    /**
473
     * 
474
     */
475
    public long getTotalResults(){
476
        String resultDocsPath = "/response/result";
477
        NodeList nodes = null;
478
        try {
479
            nodes = (NodeList) this.xpath.evaluate(resultDocsPath, this.inputSource, XPathConstants.NODESET);
480
        }
481
        catch (XPathExpressionException xpee) {
482
            return 0;
483
        }
484
 
485
        Node node = nodes.item(0);
486
 
487
        return Long.parseLong(node.getAttributes().getNamedItem("numFound").getNodeValue());
488
 
489
    }
490
        /**
491
     * 
492
     * @return
493
     */
494
    public long[] getResultEntityIDs() {
495
        String expression = "/response/result/doc/long";
496
 
497
        NodeList nodes = null;
498
        try {
499
            nodes = (NodeList) this.xpath.evaluate(expression, this.inputSource,
500
                    XPathConstants.NODESET);
501
        } 
502
        catch(XPathExpressionException xpee) {
503
            return null;
504
        }
505
 
506
        if(nodes.getLength() == 0) {
507
            return null;
508
        }
509
 
510
        long[] values = new long[nodes.getLength()];
511
        for(int i=0; i<nodes.getLength(); i++) {
512
            Node node = nodes.item(i);
513
            String value = node.getTextContent();
514
            values[i] = Long.parseLong(value);
515
        }
516
 
517
        return values;
518
    }
519
 
520
    /**
521
     * 
522
     * @return
523
     */
524
    public String[] getResultCategoryNames() {
525
        String expression = "/response/lst/lst[@name = 'facet_fields']/";
526
        expression += "lst[@name = 'Category']/int/@name";
527
 
528
        NodeList nodes = null;
529
        try {
530
            nodes = (NodeList) this.xpath.evaluate(expression, 
531
                this.inputSource, XPathConstants.NODESET);
532
        }
533
        catch (XPathExpressionException xpee) {
534
            return null;
535
        }
536
 
537
        if(nodes.getLength() == 0) {
538
            return null;
539
        }
540
 
541
        String[] values = new String[nodes.getLength()];
542
        for(int i=0; i<nodes.getLength(); i++) {
543
            Node node = nodes.item(i);
544
            values[i] = node.getTextContent();
545
        }
546
 
547
        return values;
548
    }
549
 
550
    /**
551
     * 
552
     * @return
553
     */
554
    public int[] getResultCategoryCounts() {
555
        String expression = "/response/lst/lst[@name = 'facet_fields']/";
556
        expression += "lst[@name = 'Category']/int";
557
 
558
        NodeList nodes = null;
559
        try {
560
            nodes = (NodeList) this.xpath.evaluate(expression, 
561
                this.inputSource, XPathConstants.NODESET);
562
        }
563
        catch (XPathExpressionException xpee) {
564
            return null;
565
        }
566
 
567
        if(nodes.getLength() == 0) {
568
            return null;
569
        }
570
 
571
        int[] values = new int[nodes.getLength()];
572
        for(int i=0; i<nodes.getLength(); i++) {
573
            Node node = nodes.item(i);
574
            values[i] = Integer.parseInt(node.getTextContent());
575
        }
576
 
577
        return values;
578
    }
579
 
580
    /**
581
     * 
582
     * @return
583
     */
584
    public String[]  getResultEntityNames() {
585
        String expression = "/response/result/doc/str";
586
 
587
        NodeList nodes = null;
588
        try {
589
            nodes = (NodeList) this.xpath.evaluate(expression, this.inputSource,
590
                    XPathConstants.NODESET);
591
        } 
592
        catch(XPathExpressionException xpee) {
593
            return null;
594
        }
595
 
596
        if(nodes.getLength() == 0) {
597
            return null;
598
        }
599
 
600
        String[] values = new String[nodes.getLength()];
601
        for(int i=0; i<nodes.getLength(); i++) {
602
            Node node = nodes.item(i);
603
            String value = node.getTextContent();
604
            values[i] = value;
605
        }
606
 
607
        return values;
608
    }
609
 
610
    /**
611
     * 
612
     * @param facetDefinitionID
613
     * @return
614
     */
615
    public String[] getFacetValues(String facetDefinitionID) {
616
        String expression = "/response/lst/lst[@name = 'facet_fields']/";
617
        expression += "lst[@name = '"+ facetDefinitionID +"']/int/@name";
618
 
619
        NodeList nodes = null;
620
        try {
621
            nodes = (NodeList) this.xpath.evaluate(expression, 
622
                this.inputSource, XPathConstants.NODESET);
623
        }
624
        catch (XPathExpressionException xpee) {
625
            return null;
626
        }
627
 
628
        if(nodes.getLength() == 0) {
629
            return null;
630
        }
631
 
632
        String[] values = new String[nodes.getLength()];
633
        for(int i=0; i<nodes.getLength(); i++) {
634
            Node node = nodes.item(i);
635
            values[i] = node.getTextContent();
636
        }
637
 
638
        return values;
639
    }
640
 
641
    /**
642
     * 
643
     * @param facetDefinitionID
644
     * @return
645
     */
646
    public String[] getFacetCounts(String facetDefinitionID) {
647
        String expression = "/response/lst/lst[@name = 'facet_fields']/";
648
        expression += "lst[@name = '" + facetDefinitionID + "']/int";
649
 
650
        NodeList nodes = null;
651
        try {
652
            nodes = (NodeList) this.xpath.evaluate(expression, 
653
                this.inputSource, XPathConstants.NODESET);
654
        }
655
        catch (XPathExpressionException xpee) {
656
            return null;
657
        }
658
 
659
        if(nodes.getLength() == 0) {
660
            return null;
661
        }
662
 
663
        String[] values = new String[nodes.getLength()];
664
        for(int i=0; i<nodes.getLength(); i++) {
665
            Node node = nodes.item(i);
666
            values[i] = node.getTextContent();
667
        }
668
 
669
        return values;
670
    }
671
 
672
    public static void main(String[] args){
673
        /*
674
        // Hard coded for now
675
        String[] facetDefIDs = new String[] {"F_50001", "F_50002", "F_50003", "F_50004", "F_50005", "F_50006", "F_50007", "F_50008", "F_50009"};
676
 
677
        // Hard-coded for now
678
        String[] facetLabels = new String[] {
679
            "Brand", "Price","Form Factor", "Carry In Pocket", "Cellular Technologies", 
680
            "Data Connectivity", "Camera Resolution", "Built-in Memory", 
681
            "Talk time"
682
        };
683
 
684
         */
685
        String[] facetDefIDs = new String[] {"Category","F_50002","F_50001",  "F_50006", "F_50007" };
686
        //String[] facetLabels = new String[] {"Category","Price", "Brand", "Data Connectivity", "Camera Resolution"    };
687
 
688
 
689
        String[] fqrys = {};
690
        SearchService search = new SearchService("nokia", fqrys, 0 , 20, null, null, null, -1);
691
 
692
        long[] entityIDs = search.getResultEntityIDs();
693
        log.info("entityIDs=" + Arrays.toString(entityIDs));
694
 
695
        String[] entityNames = search.getResultEntityNames();
696
        log.info("entityNames=" + Arrays.toString(entityNames));
697
        search.getFacetMap();
698
 
699
        search.getResultMap();
700
        search.getRangeQueryResultMap();
701
        search.getPriceStatsMap(new InputSource());
702
        search.getTotalResults();
703
        for (int i=0; i<facetDefIDs.length; i++) {
704
            search.getFacetCounts(facetDefIDs[i]);
705
            search.getFacetValues(facetDefIDs[i]);
706
        }
707
 
708
    }
709
 
710
 
711
    public static List<String> getAllMatches(String text) {
712
        List<String> matches = new ArrayList<String>();
713
        Matcher m = FACET_PATTERN.matcher(text);
714
        while(m.find()) {
715
            matches.add(m.group(1));
716
        }
717
        return matches;
718
    }
719
 
720
    public Map<String, Double> getDynamicPriceMap() {
721
        return this.dynamicPriceMap;
722
    }
723
 
724
}