0
votes

I am new in Grails. I am using Mahout Recommender Plugin for creating Recommender Engine. I am following this tutorial. It works fine for me.

Now What I am trying to do, I just want to do this Mahout Recommendation using Background JOB. So that User can recommendate automatically based on What they like. I am using Quartz 2.x Scheduler for Background Job purpose. How can I use Mahout as a Background JOB??

In this tutorial, You can see I have created one PrefrenceController.groovy where I am adding userID, itemID and prefrence number.

My Prefrence.groovy domain class file --

package com.rbramley.mahout

import org.apache.commons.lang.builder.HashCodeBuilder

class Preference implements Serializable {
   long userId
   long itemId
   float prefValue

   static constraints = {
       userId()
       itemId()
       prefValue range: 0.0f..5.0f
   }

   boolean equals(other) {
      if(!(other instanceof Preference)) {
         return false
      }

    other.userId == userId && other.itemId == itemId
   }

   int hashCode() {
      def builder = new HashCodeBuilder()
      builder.append userId
      builder.append itemId
      builder.toHashCode()
   }

   static mapping = {
      id composite: ['userId', 'itemId']
      version false
   }
  }

and my PrefrenceController.groovy

package com.rbramley.mahout

import org.springframework.dao.DataIntegrityViolationException

class PreferenceController {

   static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

   def index() {
       redirect(action: "list", params: params)
   }

   def list(Integer max) {
      params.max = Math.min(max ?: 10, 100)
      [preferenceInstanceList: Preference.list(params), preferenceInstanceTotal: Preference.count()]
   }

   def create() {
       [preferenceInstance: new Preference(params)]
   }

   def save() {
       def preferenceInstance = new Preference(params)
       if (!preferenceInstance.save(flush: true)) {
          render(view: "create", model: [preferenceInstance: preferenceInstance])
          return
       }

    flash.message = message(code: 'default.created.message', args: [message(code: 'preference.label', default: 'Preference'), preferenceInstance.id])
    redirect(action: "show", id: preferenceInstance.id)
    }

    def show(Long id) {
      def preferenceInstance = Preference.get(id)
      if (!preferenceInstance) {
        flash.message = message(code: 'default.not.found.message', args: [message(code: 'preference.label', default: 'Preference'), id])
        redirect(action: "list")
        return
    }

    [preferenceInstance: preferenceInstance]
  }

  def edit(Long id) {
    def preferenceInstance = Preference.get(id)
    if (!preferenceInstance) {
        flash.message = message(code: 'default.not.found.message', args: [message(code: 'preference.label', default: 'Preference'), id])
        redirect(action: "list")
        return
    }

    [preferenceInstance: preferenceInstance]
  }

  def update(Long id, Long version) {
    def preferenceInstance = Preference.get(id)
    if (!preferenceInstance) {
        flash.message = message(code: 'default.not.found.message', args: [message(code: 'preference.label', default: 'Preference'), id])
        redirect(action: "list")
        return
    }

    if (version != null) {
        if (preferenceInstance.version > version) {
            preferenceInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
                      [message(code: 'preference.label', default: 'Preference')] as Object[],
                      "Another user has updated this Preference while you were editing")
            render(view: "edit", model: [preferenceInstance: preferenceInstance])
            return
        }
    }

    preferenceInstance.properties = params

    if (!preferenceInstance.save(flush: true)) {
        render(view: "edit", model: [preferenceInstance: preferenceInstance])
        return
    }

    flash.message = message(code: 'default.updated.message', args: [message(code: 'preference.label', default: 'Preference'), preferenceInstance.id])
    redirect(action: "show", id: preferenceInstance.id)
}

def delete(Long id) {
    def preferenceInstance = Preference.get(id)
    if (!preferenceInstance) {
        flash.message = message(code: 'default.not.found.message', args: [message(code: 'preference.label', default: 'Preference'), id])
        redirect(action: "list")
        return
    }

    try {
        preferenceInstance.delete(flush: true)
        flash.message = message(code: 'default.deleted.message', args: [message(code: 'preference.label', default: 'Preference'), id])
        redirect(action: "list")
    }
    catch (DataIntegrityViolationException e) {
        flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'preference.label', default: 'Preference'), id])
        redirect(action: "show", id: id)
    }
}
}

Suppose I have added some data manually in my Database. Now When User click on RecommendController and put particular userID then It will show Recommendation. But I want to do this as a background Job. Recommendation should be suggest automatically to all users without any human intervention.

1
You said I just want to do this Mahout Recommendation using Background JOB can you expand on this what do you want the job todo for you?Alidad
Right Now I can get recommendation to particular user only by filling recommendation form which Mahout Plugin gives. But By filling manually UserID and then give recommendation is not good. It should be on background so that User can see their suggestion automaticlly based on what they like.Free-Minded

1 Answers

0
votes

If I understood your question you need an on-demand job that you can run it from your controller. To do so create a job without any trigger, then you can trigger it manually from your Controller and pass into it your parameters. This will trigger the job on the background. In the execute define what the job needs to do, you can also inject any services that you need into that job.

Controller:

BackgroundJob.triggerNow([id:params.id,userId:userId]) 

Job

class BackgroundJob {
    static triggers = {}

    def execute(context) {
        def id = context.mergedJobDataMap.get('id')
        def userId = context.mergedJobDataMap.get('userId')
        ...
    }
}