Subversion Repositories SmartDukaan

Rev

Blame | Last modification | View Log | RSS feed

package in.shop2020.web;

import in.shop2020.model.ProductSearchActivity;
import in.shop2020.model.SearchMetadata;
import in.shop2020.server.ProductSearchActivityRepository;

import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;

public class DailySearchQueryAggregatorServlet extends HttpServlet {

        private static final long serialVersionUID = -5899643747361932442L;
        private static Logger logger = Logger.getLogger(DailySearchQueryAggregatorServlet.class.getName());
        Map<String,SearchMetadata> productSearchFreq = new Hashtable<String,SearchMetadata>();
        Map<String,Double> searchClickMap = new Hashtable<String,Double>();
        private Date toDate = null;
        private Date fromDate = null;
        
        
        public void doGet(HttpServletRequest req, HttpServletResponse resp) {
        doPost(req, resp);
    }
        
        
        public void doPost(HttpServletRequest req, HttpServletResponse resp) {
                productSearchFreq = new Hashtable<String,SearchMetadata>();
                Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("IST"));
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                sdf.setTimeZone(TimeZone.getTimeZone("IST"));
        String dateStr = req.getParameter("date");
        if (dateStr != null && !dateStr.isEmpty()) {
            try {
                fromDate = sdf.parse(dateStr);
                cal.setTime(fromDate);
                cal.add(Calendar.DATE, 1);
                toDate = cal.getTime();
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }else {
                cal.set(Calendar.HOUR_OF_DAY, 0);  
                cal.set(Calendar.MINUTE, 0);  
                cal.set(Calendar.SECOND, 0);  
                cal.set(Calendar.MILLISECOND, 0);
                toDate = cal.getTime();
                cal.add(Calendar.DATE, -1);
                fromDate = cal.getTime();
        }
                
                logger.warning("toDate = "+toDate + "fromDate" + fromDate);
                //logger.warning("Product Search Frequency " + productSearchFreq.toString());
        
        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
        Query query = new Query("DataLog");
        query.addFilter("eventType", Query.FilterOperator.IN,Arrays.asList("PRODUCT_SEARCH","PRODUCT_VIEW"));
        query.addFilter("date", Query.FilterOperator.GREATER_THAN_OR_EQUAL, fromDate);
        query.addFilter("date", Query.FilterOperator.LESS_THAN, toDate);
        PreparedQuery pq = datastore.prepare(query);
        
        for (Entity result : pq.asIterable()) {
                //logger.warning(result.toString());
                if(result.getProperty("eventType").equals("PRODUCT_SEARCH")){
                        Map<String,SearchMetadata>  updatedSearchFreqMap = populateSearchDataMap(productSearchFreq, result);
                        if(updatedSearchFreqMap!=null){
                                productSearchFreq = updatedSearchFreqMap;
                        }
                }else{
                        //Calculating the frequency of ProductViews originating from ProductSearch
                        Map<String,Double> updatedClickMap = populateSearchClickMap(searchClickMap,result);
                        if(updatedClickMap!=null) {
                                searchClickMap = updatedClickMap;
                        }
                }
        }
        
        List<ProductSearchActivity> searchActivities = new ArrayList<ProductSearchActivity>();
        ProductSearchActivityRepository searchActivityRepository = new ProductSearchActivityRepository();
        
        //logger.warning(productSearchFreq.toString());
        
        for(String queryString : productSearchFreq.keySet()){
                ProductSearchActivity  searchActivity = new ProductSearchActivity();
                searchActivity.setQueryString(queryString);
                searchActivity.setDate(fromDate);
                searchActivity.setSearchCount(productSearchFreq.get(queryString).getTotalSearches());
                
                        
                        searchActivity.setSessionCountForQuery(new Long((productSearchFreq.get(queryString).getSessionIds()==null ? 0 : productSearchFreq.get(queryString).getSessionIds().size())));

                        Long tempSum = new Long(0);
                        for(Long numOfSearchResults : productSearchFreq.get(queryString).getSearchResults()){
                                tempSum+=numOfSearchResults;
                        }
                        searchActivity.setAvgNumResults(new Integer((int) (tempSum/productSearchFreq.get(queryString).getTotalSearches())));
                        searchActivity.setSearchResultClickedCount((long) ((searchClickMap.get(queryString))==null ? 0 : searchClickMap.get(queryString)));
                        
                        Double searchConversionRate = (((searchClickMap.get(queryString))==null ? 0 : searchClickMap.get(queryString))*100/(productSearchFreq.get(queryString).getTotalSearches()));
                        searchConversionRate = ((double)((long)(searchConversionRate*100)))/100; //Truncating to 2 decimal places
                        searchActivity.setSearchConvRate(searchConversionRate);
                        searchActivities.add(searchActivity);
                        //logger.warning(searchActivity.toString());
        }
        //logger.warning(searchActivities.toString());
        searchActivityRepository.createAll(searchActivities);
        }
        
        
        private Map<String,SearchMetadata> populateSearchDataMap(Map<String,SearchMetadata> productSearchFreq, Entity result){
                String searchString = (String)result.getProperty("query");
                if(searchString!=null){
                        if(productSearchFreq.containsKey(searchString)){
                                try{
                                        SearchMetadata searchObject = productSearchFreq.get(searchString);
                                        
                                        //Setting number of searches
                                        searchObject.setTotalSearches(searchObject.getTotalSearches()+1);
                                
                                        //setting number of search results
                                        List<Long> numSearchResults =searchObject.getSearchResults();
                                        numSearchResults.add((Long)result.getProperty("totalResults"));
                                        searchObject.setSearchResults(numSearchResults);
                                        
                                        //Setting frequency by category
                                        /*String categoryId = Category.findByValue(Integer.parseInt(result.getProperty("categoryId").toString())).toString();
                                        if(searchObject.getcategoryFrequency().containsKey(categoryId)) {
                                                searchObject.getcategoryFrequency().put(categoryId, (searchObject.getcategoryFrequency().get(categoryId))+1);
                                        }else {
                                                searchObject.getcategoryFrequency().put(categoryId,Long.parseLong("1"));
                                        }*/
                                        
                                        //Storing session Id of query
                                        if(!searchObject.getSessionIds().contains(result.getProperty("sessionId"))){
                                                searchObject.getSessionIds().add(result.getProperty("sessionId"));
                                        }
                                        
                                        productSearchFreq.put(searchString, searchObject);
                                }catch(Exception ex){
                                        logger.log(Level.SEVERE, "Error while populating SearchQueryMap for an existing query");
                                        return null;
                                }
                        }else{
                                try {
                                        SearchMetadata searchObject = new SearchMetadata();
                                        
                                        //Setting frequency by category
                                        /*String categoryId = Category.findByValue(Integer.parseInt(result.getProperty("categoryId").toString())).toString();
                                        Map<String, Long> categoryFrequency = new Hashtable<String, Long>();
                                        categoryFrequency.put(categoryId,Long.parseLong("1"));
                                        searchObject.setcategoryFrequency(categoryFrequency);*/
                                        
                                        //Setting number of searches
                                        searchObject.setTotalSearches(Long.parseLong("1"));
                                        
                                        //setting number of search results
                                        List<Long> numSearchResults = new ArrayList<Long>();
                                        numSearchResults.add((Long)result.getProperty("totalResults"));
                                        searchObject.setSearchResults(numSearchResults);
                                        
                                        //Storing session Id of query
                                        List<Object> sessionList = new ArrayList<Object>();
                                        sessionList.add(result.getProperty("sessionId"));
                                        searchObject.setSessionIds(sessionList);
                
                                        productSearchFreq.put(searchString,searchObject);
                                }catch(Exception ex) {
                                        logger.log(Level.SEVERE, "Exception while populating searchQueryMap for new query");
                                        return null;
                                }
                        }
                }
                return productSearchFreq;
        }

        
        private Map<String,Double> populateSearchClickMap(Map<String,Double> searchClickMap, Entity result){
                String refererUrl = (String)result.getProperty("refererUrl");
                if(refererUrl!=null){
                        if(refererUrl.contains("search?")){
                                try{
                                        String clickQuery = "";
                                        refererUrl = URLDecoder.decode(refererUrl);
                                        clickQuery = refererUrl.split("q=")[1].split("&")[0];
                                        if(searchClickMap.containsKey(clickQuery)){
                                                searchClickMap.put(clickQuery, searchClickMap.get(clickQuery)+1);
                                        }else{
                                                searchClickMap.put(clickQuery, Double.parseDouble("1"));
                                        }
                                }catch(Exception ex){
                                        logger.log(Level.SEVERE, "Error while populating SearchClickMap for refererUrl : "+refererUrl);
                                }
                        }
                }
                return searchClickMap;
        }
        
}