Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5599 amit.gupta 1
package in.shop2020.web;
2
 
3
import in.shop2020.model.ProductSearchActivity;
4
import in.shop2020.model.SearchMetadata;
5
import in.shop2020.server.ProductSearchActivityRepository;
6
 
7
import java.net.URLDecoder;
8
import java.text.ParseException;
9
import java.text.SimpleDateFormat;
10
import java.util.ArrayList;
11
import java.util.Arrays;
12
import java.util.Calendar;
13
import java.util.Date;
14
import java.util.Hashtable;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.TimeZone;
18
import java.util.logging.Level;
19
import java.util.logging.Logger;
20
 
21
import javax.servlet.http.HttpServlet;
22
import javax.servlet.http.HttpServletRequest;
23
import javax.servlet.http.HttpServletResponse;
24
 
25
import com.google.appengine.api.datastore.DatastoreService;
26
import com.google.appengine.api.datastore.DatastoreServiceFactory;
27
import com.google.appengine.api.datastore.Entity;
28
import com.google.appengine.api.datastore.PreparedQuery;
29
import com.google.appengine.api.datastore.Query;
30
 
31
public class DailySearchQueryAggregatorServlet extends HttpServlet {
32
 
33
	private static final long serialVersionUID = -5899643747361932442L;
34
	private static Logger logger = Logger.getLogger(DailySearchQueryAggregatorServlet.class.getName());
35
	Map<String,SearchMetadata> productSearchFreq = new Hashtable<String,SearchMetadata>();
36
	Map<String,Double> searchClickMap = new Hashtable<String,Double>();
37
	private Date toDate = null;
38
	private Date fromDate = null;
39
 
40
 
41
	public void doGet(HttpServletRequest req, HttpServletResponse resp) {
42
        doPost(req, resp);
43
    }
44
 
45
 
46
	public void doPost(HttpServletRequest req, HttpServletResponse resp) {
47
		productSearchFreq = new Hashtable<String,SearchMetadata>();
48
		Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("IST"));
49
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
50
		sdf.setTimeZone(TimeZone.getTimeZone("IST"));
51
        String dateStr = req.getParameter("date");
52
        if (dateStr != null && !dateStr.isEmpty()) {
53
            try {
54
            	fromDate = sdf.parse(dateStr);
55
                cal.setTime(fromDate);
56
                cal.add(Calendar.DATE, 1);
57
                toDate = cal.getTime();
58
            } catch (ParseException e) {
59
                e.printStackTrace();
60
            }
61
        }else {
62
	        cal.set(Calendar.HOUR_OF_DAY, 0);  
63
	        cal.set(Calendar.MINUTE, 0);  
64
	        cal.set(Calendar.SECOND, 0);  
65
	        cal.set(Calendar.MILLISECOND, 0);
66
	        toDate = cal.getTime();
67
	        cal.add(Calendar.DATE, -1);
68
	        fromDate = cal.getTime();
69
        }
70
 
71
		logger.warning("toDate = "+toDate + "fromDate" + fromDate);
72
		//logger.warning("Product Search Frequency " + productSearchFreq.toString());
73
 
74
        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
75
        Query query = new Query("DataLog");
76
        query.addFilter("eventType", Query.FilterOperator.IN,Arrays.asList("PRODUCT_SEARCH","PRODUCT_VIEW"));
77
        query.addFilter("date", Query.FilterOperator.GREATER_THAN_OR_EQUAL, fromDate);
78
        query.addFilter("date", Query.FilterOperator.LESS_THAN, toDate);
79
        PreparedQuery pq = datastore.prepare(query);
80
 
81
    	for (Entity result : pq.asIterable()) {
82
    		//logger.warning(result.toString());
83
    		if(result.getProperty("eventType").equals("PRODUCT_SEARCH")){
84
    			Map<String,SearchMetadata>  updatedSearchFreqMap = populateSearchDataMap(productSearchFreq, result);
85
    			if(updatedSearchFreqMap!=null){
86
    				productSearchFreq = updatedSearchFreqMap;
87
    			}
88
    		}else{
89
    			//Calculating the frequency of ProductViews originating from ProductSearch
90
    			Map<String,Double> updatedClickMap = populateSearchClickMap(searchClickMap,result);
91
    			if(updatedClickMap!=null) {
92
    				searchClickMap = updatedClickMap;
93
    			}
94
    		}
95
    	}
96
 
97
    	List<ProductSearchActivity> searchActivities = new ArrayList<ProductSearchActivity>();
98
        ProductSearchActivityRepository searchActivityRepository = new ProductSearchActivityRepository();
99
 
100
        //logger.warning(productSearchFreq.toString());
101
 
102
        for(String queryString : productSearchFreq.keySet()){
103
        	ProductSearchActivity  searchActivity = new ProductSearchActivity();
104
        	searchActivity.setQueryString(queryString);
105
        	searchActivity.setDate(fromDate);
106
        	searchActivity.setSearchCount(productSearchFreq.get(queryString).getTotalSearches());
107
 
108
 
109
			searchActivity.setSessionCountForQuery(new Long((productSearchFreq.get(queryString).getSessionIds()==null ? 0 : productSearchFreq.get(queryString).getSessionIds().size())));
110
 
111
			Long tempSum = new Long(0);
112
			for(Long numOfSearchResults : productSearchFreq.get(queryString).getSearchResults()){
113
				tempSum+=numOfSearchResults;
114
			}
115
			searchActivity.setAvgNumResults(new Integer((int) (tempSum/productSearchFreq.get(queryString).getTotalSearches())));
116
			searchActivity.setSearchResultClickedCount((long) ((searchClickMap.get(queryString))==null ? 0 : searchClickMap.get(queryString)));
117
 
118
			Double searchConversionRate = (((searchClickMap.get(queryString))==null ? 0 : searchClickMap.get(queryString))*100/(productSearchFreq.get(queryString).getTotalSearches()));
119
			searchConversionRate = ((double)((long)(searchConversionRate*100)))/100; //Truncating to 2 decimal places
120
			searchActivity.setSearchConvRate(searchConversionRate);
121
			searchActivities.add(searchActivity);
122
			//logger.warning(searchActivity.toString());
123
        }
124
        //logger.warning(searchActivities.toString());
125
        searchActivityRepository.createAll(searchActivities);
126
	}
127
 
128
 
129
	private Map<String,SearchMetadata> populateSearchDataMap(Map<String,SearchMetadata> productSearchFreq, Entity result){
130
		String searchString = (String)result.getProperty("query");
131
		if(searchString!=null){
132
			if(productSearchFreq.containsKey(searchString)){
133
				try{
134
					SearchMetadata searchObject = productSearchFreq.get(searchString);
135
 
136
					//Setting number of searches
137
					searchObject.setTotalSearches(searchObject.getTotalSearches()+1);
138
 
139
					//setting number of search results
140
					List<Long> numSearchResults =searchObject.getSearchResults();
141
					numSearchResults.add((Long)result.getProperty("totalResults"));
142
					searchObject.setSearchResults(numSearchResults);
143
 
144
					//Setting frequency by category
145
					/*String categoryId = Category.findByValue(Integer.parseInt(result.getProperty("categoryId").toString())).toString();
146
					if(searchObject.getcategoryFrequency().containsKey(categoryId)) {
147
						searchObject.getcategoryFrequency().put(categoryId, (searchObject.getcategoryFrequency().get(categoryId))+1);
148
					}else {
149
						searchObject.getcategoryFrequency().put(categoryId,Long.parseLong("1"));
150
					}*/
151
 
152
					//Storing session Id of query
153
					if(!searchObject.getSessionIds().contains(result.getProperty("sessionId"))){
154
						searchObject.getSessionIds().add(result.getProperty("sessionId"));
155
					}
156
 
157
					productSearchFreq.put(searchString, searchObject);
158
				}catch(Exception ex){
159
					logger.log(Level.SEVERE, "Error while populating SearchQueryMap for an existing query");
160
					return null;
161
				}
162
			}else{
163
				try {
164
					SearchMetadata searchObject = new SearchMetadata();
165
 
166
					//Setting frequency by category
167
					/*String categoryId = Category.findByValue(Integer.parseInt(result.getProperty("categoryId").toString())).toString();
168
					Map<String, Long> categoryFrequency = new Hashtable<String, Long>();
169
					categoryFrequency.put(categoryId,Long.parseLong("1"));
170
					searchObject.setcategoryFrequency(categoryFrequency);*/
171
 
172
					//Setting number of searches
173
					searchObject.setTotalSearches(Long.parseLong("1"));
174
 
175
					//setting number of search results
176
					List<Long> numSearchResults = new ArrayList<Long>();
177
					numSearchResults.add((Long)result.getProperty("totalResults"));
178
					searchObject.setSearchResults(numSearchResults);
179
 
180
					//Storing session Id of query
181
					List<Object> sessionList = new ArrayList<Object>();
182
					sessionList.add(result.getProperty("sessionId"));
183
					searchObject.setSessionIds(sessionList);
184
 
185
					productSearchFreq.put(searchString,searchObject);
186
				}catch(Exception ex) {
187
					logger.log(Level.SEVERE, "Exception while populating searchQueryMap for new query");
188
					return null;
189
				}
190
			}
191
		}
192
		return productSearchFreq;
193
	}
194
 
195
 
196
	private Map<String,Double> populateSearchClickMap(Map<String,Double> searchClickMap, Entity result){
197
		String refererUrl = (String)result.getProperty("refererUrl");
198
		if(refererUrl!=null){
199
			if(refererUrl.contains("search?")){
200
				try{
201
					String clickQuery = "";
202
					refererUrl = URLDecoder.decode(refererUrl);
203
					clickQuery = refererUrl.split("q=")[1].split("&")[0];
204
					if(searchClickMap.containsKey(clickQuery)){
205
						searchClickMap.put(clickQuery, searchClickMap.get(clickQuery)+1);
206
					}else{
207
						searchClickMap.put(clickQuery, Double.parseDouble("1"));
208
					}
209
				}catch(Exception ex){
210
					logger.log(Level.SEVERE, "Error while populating SearchClickMap for refererUrl : "+refererUrl);
211
				}
212
			}
213
		}
214
		return searchClickMap;
215
	}
216
 
217
}