Rev 4980 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
package in.shop2020.serving.services;import in.shop2020.model.v1.catalog.InventoryService.Client;import in.shop2020.model.v1.catalog.InventoryServiceException;import in.shop2020.model.v1.catalog.status;import in.shop2020.model.v1.catalog.Item;import in.shop2020.thrift.clients.CatalogClient;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;import org.apache.log4j.Logger;import org.apache.thrift.TException;import org.apache.thrift.transport.TTransportException;/**** @author rajveer** Auto suggest service will help user to search some term. This is based on turnary search tree.*/public class AutoSuggestService{private Node root;private static Logger log = Logger.getLogger(AutoSuggestService.class);private static AutoSuggestService autoSuggestService;static{synchronized(AutoSuggestService.class){autoSuggestService = new AutoSuggestService();autoSuggestService.initialize();}}private void initialize() {log.info("Starting instance of Autosuggest service");CatalogClient catalogServiceClient;try {catalogServiceClient = new CatalogClient();Client client = catalogServiceClient.getClient();List<Item> items = new ArrayList<Item>();items.addAll(client.getAllItemsByStatus(status.ACTIVE));items.addAll(client.getAllItemsByStatus(status.PAUSED));items.addAll(client.getAllItemsByStatus(status.PAUSED_BY_RISK));Set<Long> processedSet = new HashSet<Long>();for(Item item: items){if(!processedSet.contains(item.getCatalogItemId())){processedSet.add(item.getCatalogItemId());addItemName(AutoSuggestService.getProductTitle(item));}}} catch (TTransportException e) {log.error("Error while making thrift connection", e);} catch (InventoryServiceException e) {log.error("Inventory Service exception", e);} catch (TException e) {log.error("Thrift exception", e);}log.info("Done with starting Autosuggest service");}public static AutoSuggestService getAutoSuggestServiceInstance(){return autoSuggestService;}/*** Get the title of the product from catalog service.* @param item* @return*/private static String getProductTitle(Item item){String title = ((item.getBrand() != null) ? item.getBrand().trim() + " " : "")+ ((item.getModelName() != null) ? item.getModelName().trim() + " " : "")+ (( item.getModelNumber() != null ) ? item.getModelNumber().trim() : "" );title = title.replaceAll(" ", " ");return title;}private Node addChars(char[] s, int position, Node node, String string){if (node == null) {node = new Node(s[position], null);}if (s[position] < node.storedChar) {node.left = addChars(s, position, node.left, string);}else if (s[position] > node.storedChar) {node.right = addChars(s, position, node.right, string);}else{if (position + 1 == s.length) { node.addItem(string); }else { node.center = addChars(s, position + 1, node.center, string); }}return node;}public void addStringPart(String part, String string){if (part == null || part == "") return;root = addChars(part.toCharArray(), 0, root, string);}/*** Add String to the tree* @param string*/private void addItemName(String string) {if (string == null || string == "") return;String[] parts = string.trim().toLowerCase().split("\\s+");for(String part : parts){addStringPart(part, string);}}/*** Get list of matching product names.* @param str* @param resultCount* @return*/public List<String> getMatchingQueries(String str, int resultCount){Set<String> totalSet = new HashSet<String>();String[] parts = str.trim().toLowerCase().split("\\s+");for(String part : parts){Node node = getPartialMatchNode(part);Set<String> set = new HashSet<String>();getChildElements(node, set);if(totalSet.isEmpty()){totalSet.addAll(set);}else{totalSet.retainAll(set);}}List<String> items = new ArrayList<String>(totalSet);if(items.size() > resultCount){return items.subList(0, resultCount-1);}else{return items;}}/*** Return the node till which we are able to match the word.* @param str* @return*/private Node getPartialMatchNode(String str){char[] s = str.toCharArray();int pos = 0;Node node = root;while (node != null){if (s[pos] < node.storedChar) { node = node.left; }else if (s[pos] > node.storedChar) { node = node.right; }else{if (++pos == s.length){if(node.center==null){return node;}else{return node.center;}}node = node.center;}}return node;}private void getChildElements(Node node, Set<String> set){if(node == null){return;}if(node.itemSet != null){if(node.itemSet != null && !node.itemSet.isEmpty()){set.addAll(node.itemSet);}return;}else{getChildElements(node.center, set);}getChildElements(node.left, set);getChildElements(node.right, set);}@Overridepublic String toString() {return "AutoSuggest [root=" + root + "]";}public static void main(String[] args) throws Exception {AutoSuggestService as = new AutoSuggestService();as.addItemName("Nokia N8");as.addItemName("Nokia C5-00");as.addItemName("Nokia C3-00");as.addItemName("Nokia X2-01");as.addItemName("Samsung Galaxy Pro");as.addItemName("Samsung Galaxy Pop");as.addItemName("Samsung Galaxy 551 I5510");System.out.println(as.getMatchingQueries("noki", 10));System.out.println(as.getMatchingQueries("nok", 10));System.out.println(as.getMatchingQueries("n8", 10));System.out.println(as.getMatchingQueries("po gala", 10));}}class Node{char storedChar;Node left, center, right;Set<String> itemSet;public void addItem(String itemName){if(itemSet == null || itemSet.isEmpty()){itemSet = new HashSet<String>();}itemSet.add(itemName);}public Node(char ch, String itemName){this.storedChar = ch;if(itemName != null){itemSet = new HashSet<String>();itemSet.add(itemName);}}@Overridepublic String toString() {return "Node [storedChar=" + storedChar + ", left=" + left+ ", center=" + center + ", right=" + right + ", itemSet="+ itemSet + "]";}}