Pergunta

Tenho um problema de desenvolvimento de webapp para o qual desenvolvi uma solução, mas estou tentando encontrar outras ideias que possam contornar alguns problemas de desempenho que estou vendo.

declaração do problema:

  • um usuário insere várias palavras-chave/tokens
  • o aplicativo procura correspondências com os tokens
  • precisa de um resultado para cada token
    • ou seja, se uma entrada tiver 3 tokens, preciso do ID da entrada 3 vezes
  • classifique os resultados
    • atribuir X pontos para correspondência de token
    • classifique os IDs de entrada com base em pontos
    • se os valores dos pontos forem iguais, use a data para classificar os resultados

O que eu quero fazer, mas ainda não descobri, é enviar 1 consulta que retorne algo semelhante aos resultados de um in (), mas retorne um ID de entrada duplicado para cada token correspondente a cada ID de entrada verificado.

Existe uma maneira melhor de fazer isso do que estou fazendo, usando várias consultas individuais executando uma consulta por token?Em caso afirmativo, qual é a maneira mais fácil de implementá-los?

editar
Já tokenizei as entradas, então, por exemplo, "ver spot run" tem um ID de entrada 1 e três tokens, 'see', 'spot', 'run', e esses estão em uma tabela de tokens separada, com IDs de entrada relevantes para eles, para que a tabela fique assim:

'see', 1 
'spot', 1 
'run', 1 
'run', 2 
'spot', 3 
Foi útil?

Solução

você poderia conseguir isso em uma consulta usando 'UNION ALL' no MySQL.

Basta percorrer os tokens em PHP criando um UNION ALL para cada token:

por exemplo, se os tokens forem 'x', 'y' e 'z', sua consulta pode ser parecida com isto

SELECT * FROM `entries` 
WHERE token like "%x%" union all 
    SELECT * FROM `entries` 
    WHERE token like "%y%" union all 
        SELECT * FROM `entries` 
        WHERE token like "%z%" ORDER BY score ect...

A cláusula order deve operar em todo o conjunto de resultados como um só, que é o que você precisa.

Em termos de desempenho, não será tão rápido (suponho), no entanto, com bancos de dados, a principal sobrecarga em termos de velocidade geralmente é enviar a consulta ao mecanismo de banco de dados a partir do PHP e receber os resultados.Com esta técnica isso acontece apenas uma vez em vez de uma vez por token, então o desempenho aumentará, só não sei se será suficiente.

Outras dicas

Eu sei que isso não é estritamente uma resposta à pergunta que você está fazendo mas se sua tabela tiver milhares em vez de milhões de linhas, então uma solução FULLTEXT pode ser a melhor opção aqui.

No MySQL, quando você usa MATCH em sua coluna indexada, cada palavra-chave fornecida receberá uma pontuação de relevância (calculada aproximadamente pelo número de vezes que cada palavra-chave foi mencionada) que será mais precisa que o seu método e certamente mais eficiente para múltiplas palavras-chave.

Veja aqui:http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

Se você estiver usando o padrão UNION ALL, você também pode incluir as seguintes partes em sua consulta:

SELECT COUNT(*) AS C
...
GROUP BY ID
ORDER BY c DESC

Embora este seja um exemplo realmente trivial, ele fornece a frequência das correspondências para cada resultado e pode ser uma pseudo classificação para começar.

Você provavelmente obterá um desempenho muito melhor se usar uma estrutura de dados projetada para tarefas de pesquisa em vez de um banco de dados.Por exemplo, você pode tentar construir um índice invertido.Em vez de escrever você mesmo, no entanto, você também pode querer pesquisar algo como Lucena que faz a maior parte do trabalho para você.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top