Como você faria para criar um algoritmo de busca para um CRM?

5

Eu sei que esta questão é muito ampla, mas tudo o que eu realmente preciso é de alguma estrutura de código de boas práticas ou um link para um bom tutorial.

Estou trabalhando em um CRM que roda em php e mysql. Atualmente, nossa consulta de pesquisa é algo assim:

SELECT * FROM contatos ONDE nome LIKE '% ric flair%'

Agora, isso é muito estúpido, mas é isso que significa. Na verdade, estamos usando declarações preparadas, disparando mais de 30 consultas de linha e juntando muitas tabelas para verificar a propriedade e tudo o mais.

Mas se o usuário digitar rick flair ou ric m flair , a consulta de pesquisa não o encontrará. Agora, eu poderia dividir a string em três termos de pesquisa, %ric% , %m% , %flair% , e trabalhar a partir daí, mas então eu vou pegar todos os caras chamados Ric (e Rick), e então Ric Flair poderia estar em qualquer lugar entre os resultados da pesquisa.

Eu sinto que estou fazendo isso como um amador, e quando eu olho informações sobre algoritmos de busca, tudo o que posso encontrar são pessoas que querem ser o Google.

Qualquer conselho a respeito disso seria apreciado.

Para esclarecer

Esta é uma função de pesquisa global que examina contatos, telefones, e-mails, tarefas, oportunidades de vendas, conversas e notas, procurando por qualquer coisa que tenha ou esteja conectada à sua string de pesquisa (neste caso, Ric Flair).

O principal objetivo aqui é ter uma pesquisa "mais inteligente", de modo que, se você digitar rick flair ou ric m. flair , ela ainda terá uma boa chance de retornar o contato ric flair no topo, mesmo que você pode ter pessoas chamadas Rick na sua lista de contatos. Talvez seja porque o último nome correspondeu e isso é mais importante? Ou estou pensando demais nisso?

    
por Captain Hypertext 31.10.2016 / 14:32
fonte

3 respostas

3

Você pode querer dar uma olhada em Lucene . Está escrito em Java, mas você pode usá-lo do PHP através de sua porta Zend ou Solr , embora eu ache que o Solr pode não ser uma solução, já que você provavelmente quer algo embutido em seu CMS.

A ideia é criar um índice a partir de todos os dados pesquisáveis e, em seguida, pesquisar esse índice. Tem a vantagem de poder ser muito mais rápido que as consultas de banco de dados. Você também pode implementar um sistema de pontuação, para que alguns registros apareçam mais acima na lista de resultados, se forem mais relevantes para o usuário. Uma possível desvantagem é que você precisa atualizar o índice toda vez que os dados forem atualizados.

Se a abordagem do Lucene não se encaixar no seu cenário, você poderia usar uma combinação de PHP e código do banco de dados. Uma exibição ou um procedimento armazenado pode atuar como um índice substituto, agregando os dados pesquisáveis. Você precisaria dividir strings por espaços em branco e isso poderia torná-lo bastante lento, mas você vai chegar lá. O código PHP será responsável por criar a cláusula WHERE (você pode dar uma olhada em como a Solr implementa estratégias de consulta para sugestões como fonte de inspiração). Supondo que você tenha Id , Name e Score como campos de índice e dois registros de contato com Id=1, FirstName="Ric", LastName="Flair" e Id=2, FirstName="Ric", LastName="Flare" , os registros de índice ficariam mais ou menos assim:

+--------------+-------+
| Id | Name    | Score |
+----+---------+-------+
| 1  | Ric     |   1   |
+----+---------+-------+
| 1  | Flair   |   1   |
+----+---------+-------+
| 2  | Ric     |   1   |
+----+---------+-------+
| 2  | Flare   |   1   |
+----+---------+-------+

Um exemplo pode ter esta aparência (SQL Server):

DECLARE @index TABLE (
    Id INT NOT NULL,
    Name NVARCHAR(50) NOT NULL,
    Score INT NOT NULL
)

INSERT INTO @index (Id, Name, Score) VALUES (1, 'Ric', 1)
INSERT INTO @index (Id, Name, Score) VALUES (1, 'Flair', 1)
INSERT INTO @index (Id, Name, Score) VALUES (2, 'Ric', 1)
INSERT INTO @index (Id, Name, Score) VALUES (2, 'Flare', 1)

SELECT
    Id,
    SUM(Score) AS Score
FROM
    @index
WHERE
    Name = 'Ric'
    OR Name = 'Flair'
GROUP BY
    Id
ORDER BY
    Score DESC

Ric Flair teria uma pontuação mais alta, pois corresponde aos dois valores, aparecendo primeiro nos resultados da pesquisa.

O índice também pode conter campos de título e resumo a serem usados como valores a serem exibidos na página de resultados da pesquisa. Ou você pode unir os resultados com uma visualização que pré-selecione esses valores.

Você pode brincar com as condições na cláusula WHERE ou com o campo Score (você pode atribuir pontuações diferentes a diferentes tipos de registros ou propriedades) para obter uma experiência de pesquisa mais refinada.

    
por 01.11.2016 / 10:10
fonte
2

Eu procuraria em Elasticsearch .

O Elasticsearch é uma espécie de banco de dados de documentos. É um pouco como o MongoDB, mas foi projetado para pesquisas de texto muito sofisticadas. Acredito que o próprio Stack Exchange usa o Elasticsearch para a caixa de pesquisa na parte superior da página. Também faz parte do ELK (que significa Elasticsearch, Logstash e Kibana). Ele é construído sobre o Lucene, mas tem muita funcionalidade extra para pesquisas que você não gostaria de ter para construir sozinho.

Eu encontrei este pacote para usar o Elasticsearch do Laravel. Você terá que integrá-lo em sua infra-estrutura de alguma forma, mas, em troca, obterá recursos de pesquisa muito eficientes sem muito trabalho extra.

Solr é semelhante; Ele também é construído sobre o Lucene e oferece poderosos recursos de pesquisa. Qualquer uma delas é uma boa escolha, muito mais poderosa do que o SQL LIKE e mais fácil de usar do que o Lucene diretamente.

    
por 01.11.2016 / 23:42
fonte
0

Você pode normalizar os dados para procurar Ric Flair como uma entidade pessoa primeiro e depois exibir os contatos dessa pessoa. Essa é uma forma de Big CRM e é adequada se a Ric for importante para você, um cliente. Você deve esperar um controle de pesquisa sofisticado para entidades pessoais por meio de muitos atributos de dados.

Muitas vezes você não deseja criar uma pessoa a cada vez, por exemplo, como um contato alternativo para um pedido. Nesse caso, você não pode fazer muito, mas fornecer aos operadores um padrão claro e / ou instruções sobre como preencher o campo de nome durante a captura de dados.

A divisão do padrão de pesquisa por espaços em branco naturalmente produziria mais resultados. No entanto, meu palpite é que os usuários não gostariam, já que esse não é um padrão padrão.

    
por 31.10.2016 / 15:30
fonte