/** * Copyright 2012 plista GmbH (http://www.plista.com/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License. */ package org.plista.kornakapi.web.servlets; import org.apache.mahout.cf.taste.common.NoSuchItemException; import org.apache.mahout.cf.taste.common.NoSuchUserException; import org.apache.mahout.cf.taste.common.TasteException; import org.apache.mahout.cf.taste.impl.common.FastIDSet; import org.apache.mahout.cf.taste.recommender.IDRescorer; import org.apache.mahout.cf.taste.recommender.RecommendedItem; import org.plista.kornakapi.KornakapiRecommender; import org.plista.kornakapi.core.recommender.FixedCandidatesIDRescorer; import org.plista.kornakapi.web.Parameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.List; /** servlet to request recommendations */ public class RecommendServlet extends BaseServlet { private static final Logger log = LoggerFactory.getLogger(RecommendServlet.class); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int howMany = getParameterAsInt(request, Parameters.HOW_MANY, Parameters.DEFAULT_HOW_MANY); IDRescorer rescorer = null; String label = getParameter(request, Parameters.LABEL, false); String recommenderName = getParameter(request, Parameters.RECOMMENDER, true) + "_" + label; if(!containsTrainer(recommenderName)){ if (log.isInfoEnabled()) { log.info("No recommender assigned for label {}", label); } try { createRecommenderForLabel(label); } catch (TasteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } FastIDSet candidates = storages().get(label).getCandidates(label); rescorer = new FixedCandidatesIDRescorer(candidates); KornakapiRecommender recommender = recommender(recommenderName); try { List<RecommendedItem> recommendedItems; if (hasParameter(request, Parameters.USER_ID)) { long userID = getParameterAsLong(request, Parameters.USER_ID, false); long duration = 0; long[] itemIDs = null; if (hasParameter(request, Parameters.ITEM_IDS)) { itemIDs = getParameterAsLongArray(request, Parameters.ITEM_IDS); } if(itemIDs == null || (itemIDs.length == 1 && itemIDs[0] == 0)){ //if there are no seen itemids provided long start = System.currentTimeMillis(); recommendedItems = recommender.recommend(userID, howMany, rescorer); duration = System.currentTimeMillis() - start; }else{ long start = System.currentTimeMillis(); recommendedItems = recommender.recommend(userID, itemIDs, howMany, rescorer); duration = System.currentTimeMillis() - start; } if (log.isInfoEnabled()) { log.info("{} recommendations for user {} in {} ms", new Object[] { recommendedItems.size(), userID, duration }); } } else if (hasParameter(request, Parameters.ITEM_IDS)) { long[] itemIDs = getParameterAsLongArray(request, Parameters.ITEM_IDS); long start = System.currentTimeMillis(); recommendedItems = recommender.recommendToAnonymous(itemIDs, howMany, rescorer); long duration = System.currentTimeMillis() - start; if (log.isInfoEnabled()) { log.info("{} recommendations for anonymous user {} in {} ms", new Object[] {recommendedItems.size(), itemIDs[0], duration}); } } else { throw new IllegalStateException("Parameter [" + Parameters.USER_ID + "] or [" + Parameters.ITEM_IDS + "] " + "must be supplied!"); } PrintWriter writer = response.getWriter(); response.setContentType("application/json"); String separator = ""; writer.write("["); for (RecommendedItem recommendedItem : recommendedItems) { writer.write(separator); writer.write("{\"itemID\":"); writer.write(String.valueOf(recommendedItem.getItemID())); writer.write(",\"value\":"); writer.write(String.valueOf(recommendedItem.getValue())); writer.write("}"); separator = ","; } writer.write("]"); } catch (NoSuchUserException e) { if (log.isInfoEnabled()) { log.info("Unkown User: {}", e.getMessage()); } } catch (NoSuchItemException e) { if (log.isInfoEnabled()) { log.info("Unknown Item: {}", e.getMessage()); } }catch (TasteException e) { if (log.isInfoEnabled()) { log.info("Unknown Item: {}", e.getMessage()); } throw new ServletException(e); } } }