Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package snu.controladores.indexador; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import snu.controladores.MusicaJpaController; import snu.controladores.VocabuloJpaController; import snu.dto.Pair; import snu.entidades.musica.Musica; import snu.entidades.musica.indexador.ObjetoListaInvertida; import snu.entidades.musica.indexador.Vocabulo; import snu.util.ProcessadorDeConsultasUtil; /** * Classe que possui as funes para realizar o processamento de consultas * * @author Washington Luis */ public class ProcessadorDeConsultas { private List<Musica> listaOrdenada; public ProcessadorDeConsultas() { this.listaOrdenada = new ArrayList<>(); } /** * Realiza todo o processamento da consulta. Utiliza o Modelo Vetorial para * busca por trecho. * * @param consulta * @throws java.io.IOException */ public void processar(String consulta) throws IOException { MusicaJpaController musicaController = MusicaJpaController.getInstancia(); IndexadorController indexadorController = IndexadorController.getInstancia(); List<String> tokens = tokenizeString(indexadorController.getBrazilianAnalyzer(), indexadorController.preProcessar(consulta)); //Hashing utilizado para no repetir ids de documentos List<Pair<Long, Double>> similaridadesDocumentos = new ArrayList<>(); //Carrega o controlador VocabuloJpaController vocabuloController = VocabuloJpaController.getInstancia(); //Verifica a quantidade de msicas presentes no banco Integer quantidadeDocumentos = musicaController.getMusicaCount(); /* Para cada token encontrado, procura-se o vocbulo no banco WARNING: Tamanho da lista tokens pode ser diferente da quantidades de tokens realmente utilizados. */ HashMap<Long, List<Pair<String, Double>>> matrizPesos = new HashMap<>(); //Colocar na matriz de pesos tambm a consulta (Id do documento da consulta/query 0) HashMap<String, Double> pesosConsulta = new HashMap<>(); for (String token : tokens) { Vocabulo vocabulo = vocabuloController.findVocabuloByToken(token); if (vocabulo != null) { for (ObjetoListaInvertida objetoListInvertida : vocabulo.getListaInvertida()) { Long idDocumentoMusica = objetoListInvertida.getIdDocumentoMusica(); if (matrizPesos.containsKey(idDocumentoMusica)) { matrizPesos.get(idDocumentoMusica).add(new Pair<>(token, ProcessadorDeConsultasUtil .calcularPeso(objetoListInvertida, quantidadeDocumentos))); } else { List<Pair<String, Double>> listaInvertidaPesos = new ArrayList<>(); listaInvertidaPesos.add(new Pair<>(token, ProcessadorDeConsultasUtil .calcularPeso(objetoListInvertida, quantidadeDocumentos))); matrizPesos.put(idDocumentoMusica, listaInvertidaPesos); } } //Adiciona token e valor na matriz de pesos pesosConsulta.put(token, ProcessadorDeConsultasUtil.calcularPeso(vocabulo, tokens, quantidadeDocumentos)); } } //Definindo valor fixo no clculo para evitar reclculo double sqrt_wiq, somatorioWiq = 0.; for (Map.Entry<String, Double> entradaWiq : pesosConsulta.entrySet()) { somatorioWiq += Math.pow(entradaWiq.getValue().doubleValue(), 2); } sqrt_wiq = Math.sqrt(somatorioWiq); //Clculos das similaridades MODELO VETORIAL for (Map.Entry<Long, List<Pair<String, Double>>> entradaPesos : matrizPesos.entrySet()) { double numerador = 0., denominador, somatorioWij = 0., similaridade; for (Pair<String, Double> entradaWij : entradaPesos.getValue()) { numerador += entradaWij.getSecond() * pesosConsulta.get(entradaWij.getFirst()); somatorioWij += Math.pow(entradaWij.getSecond(), 2); } denominador = Math.sqrt(somatorioWij) * sqrt_wiq; //Calcula a similaridade similaridade = numerador / denominador; similaridadesDocumentos.add(new Pair<>(entradaPesos.getKey(), similaridade)); } //Ordena a lista por maior similaridade Collections.sort(similaridadesDocumentos); List<Long> idsDocumentos = new ArrayList<>(); for (Pair<Long, Double> par : similaridadesDocumentos) { idsDocumentos.add(par.getFirst()); } this.listaOrdenada = musicaController.findMusicaByIdsDocumentos(idsDocumentos); } /** * Realiza a tokenizao de uma string (Pega as palavras com split e extrai * seu radical) * * @param analyzer * @param string * @return * @throws IOException */ private List<String> tokenizeString(Analyzer analyzer, String string) throws IOException { List<String> result = new ArrayList<>(); TokenStream stream = analyzer.tokenStream(null, new StringReader(string)); stream.reset(); while (stream.incrementToken()) { result.add(stream.getAttribute(CharTermAttribute.class).toString()); } return result; } public List<Musica> getListaOrdenada() { return listaOrdenada; } public void setListaOrdenada(List<Musica> listaOrdenada) { this.listaOrdenada = listaOrdenada; } }