Como fazer com que as principais pesquisas de texto completo com caracteres curinga funcionem no SQL Server?

StackOverflow https://stackoverflow.com/questions/3400

  •  08-06-2019
  •  | 
  •  

Pergunta

Observação: EU sou usando os recursos de pesquisa de texto completo do SQL, cláusulas CONTAINS e tudo mais - o * é o curinga em texto completo, % é apenas para cláusulas LIKE.

Já li em vários lugares que pesquisas com "caracteres curinga principais" (por exemplo,usar "*overflow" para corresponder a "stackoverflow") não é suportado no MS SQL.Estou pensando em usar um Função CLR para adicionar correspondência de regex, mas estou curioso para ver que outras soluções as pessoas podem ter.

Mais informações: Você pode adicionar o asterisco apenas no final da palavra ou frase. - junto com minha experiência empírica:Ao combinar "myvalue", "my*" funciona, mas "(asterisk)value" não retorna nenhuma correspondência, ao fazer uma consulta tão simples como:

SELECT * FROM TABLENAME WHERE CONTAINS(TextColumn, '"*searchterm"');

Portanto, minha necessidade de uma solução alternativa.Estou usando a pesquisa em meu site apenas em uma página de pesquisa real - portanto, ela precisa funcionar basicamente da mesma maneira que o Google (aos olhos de um usuário do tipo Joe Sixpack).Não é tão complicado, mas esse tipo de partida não deveria falhar.

Nenhuma solução correta

Outras dicas

Solução alternativa apenas para curinga inicial:

  • armazenar o texto invertido em um campo diferente (ou na visualização materializada)
  • crie um índice de texto completo nesta coluna
  • encontre o texto invertido com um *

    SELECT * 
    FROM TABLENAME 
    WHERE CONTAINS(TextColumnREV, '"mrethcraes*"');
    

É claro que existem muitas desvantagens, apenas para uma solução rápida ...

Sem mencionar CONTÉM-ESTÁVEL...

O problema com os principais curingas:Eles não podem ser indexados, portanto você está fazendo uma varredura completa da tabela.

É possível utilizar o curinga “*” no final da palavra ou frase (pesquisa de prefixo).

Por exemplo, esta consulta encontrará todos os "datab", "database", "databases"...

SELECT * FROM SomeTable WHERE CONTAINS(ColumnName, '"datab*"')

Mas, infelizmente, não é possível pesquisar com curinga inicial.

Por exemplo, esta consulta não encontrará "banco de dados"

SELECT * FROM SomeTable WHERE CONTAINS(ColumnName, '"*abase"')

Talvez para adicionar clareza a este tópico, em meus testes no 2008 R2, Franjo está correto acima.Ao lidar com pesquisa de texto completo, pelo menos ao usar a frase CONTAINS, você não pode usar um início , apenas um rastro funcionalmente.* é o curinga, não% no texto completo.

Alguns sugeriram que * seja ignorado.Esse não parece ser o caso, meus resultados parecem mostrar que a funcionalidade * final funciona.Acho que os * iniciais são ignorados pelo mecanismo.

Meu problema adicional, entretanto, é que a mesma consulta, com um * à direita, que usa texto completo com curingas, funcionou relativamente rápido em 2005 (20 segundos) e diminuiu para 12 minutos após a migração do banco de dados para 2008 R2.Parece que pelo menos um outro usuário teve resultados semelhantes e iniciou uma postagem no fórum que adicionei ...FREETEXT ainda funciona rápido, mas algo "parece" ter mudado com a maneira como 2008 processa o final * em CONTAINS.Eles fornecem todos os tipos de avisos no Upgrade Advisor de que "melhoraram" o FULL TEXT para que seu código possa quebrar, mas infelizmente eles não fornecem nenhum aviso específico sobre determinados códigos obsoletos, etc.... apenas um aviso de que eles mudaram, use por sua conta e risco.

http://social.msdn.microsoft.com/Forums/ar-SA/sqlsearch/thread/7e45b7e4-2061-4c89-af68-febd668f346c

Talvez este seja o impacto mais próximo da MS relacionado a esses problemas... http://msdn.microsoft.com/en-us/library/ms143709.aspx

Uma coisa que vale a pena ter em mente é que as principais consultas curinga têm um desempenho premium significativo, em comparação com outros usos de curinga.

O caractere curinga no SQL Server é o % assinar e funciona muito bem, inicial, final ou não.

Dito isso, se você for fazer qualquer tipo de pesquisa séria de texto completo, considerarei utilizar os recursos de índice de texto completo.Usando % e _ curingas farão com que seu banco de dados sofra um sério impacto no desempenho.

Nos Manuais Online do SQL Server:

Para gravar consultas de texto completo no Microsoft SQL Server 2005, você deve aprender como usar os predicados de contém e freeText Transact-SQL, e as funções com valor de linha de linhas de linha contém e FreeTexttable.

Isso significa que todas as consultas escritas acima com% e _ não são consultas de texto completo válidas.

Aqui está um exemplo da aparência de uma consulta ao chamar a função CONTAINSTABLE.

Selecione Rank, *no tableName, contenhastable (nome do tablename, *, '" *Wildcard"') Where [key] = tableName.pk Ordem por SearchTable.Rank Desc

Para que a função CONTAINSTABLE saiba que estou usando uma pesquisa curinga, preciso colocá-la entre aspas duplas.Posso usar o caractere curinga * no início ou no final.Há muitas outras coisas que você pode fazer ao criar a string de pesquisa para a função CONTAINSTABLE.Você pode pesquisar uma palavra próxima a outra palavra, pesquisar palavras flexionais (dirigir = direciona, dirigir, dirigir e dirigir) e pesquisar sinônimo de outra palavra (metal pode ter sinônimos como alumínio e aço).

Acabei de criar uma tabela, coloquei um índice de texto completo na tabela e fiz algumas pesquisas de teste e não tive problemas, então a pesquisa curinga funciona conforme o esperado.

[Atualizar]

Vejo que você atualizou sua pergunta e sabe que precisa usar uma das funções.

Você ainda pode pesquisar com o curinga no início, mas se a palavra não for uma palavra completa após o curinga, será necessário adicionar outro curinga no final.

Example:  "*ildcar" will look for a single word as long as it ends with "ildcar".

Example:  "*ildcar*" will look for a single word with "ildcar" in the middle, which means it will match "wildcard".  [Just noticed that Markdown removed the wildcard characters from the beginning and ending of my quoted string here.]

[Atualização nº 2]

Dave Ward - Usar um curinga com uma das funções não deve ser um grande sucesso no desempenho.Se eu criei uma string de pesquisa com apenas "*", ela não retornará todas as linhas; no meu caso de teste, ela retornou 0 registros.

Apenas para sua informação, o Google não faz pesquisas ou truncamentos de substring, à direita ou à esquerda.Eles têm um caractere curinga * para localizar palavras desconhecidas em uma frase, mas não uma palavra.

O Google, junto com a maioria dos mecanismos de busca de texto completo, configura um índice invertido baseado na ordem alfabética das palavras, com links para seus documentos de origem.A pesquisa binária é extremamente rápida, mesmo para índices enormes.Mas é realmente muito difícil fazer um truncamento à esquerda neste caso, porque perde a vantagem do índice.

Como parâmetro em um procedimento armazenado, você pode usá-lo como:

ALTER procedure [dbo].[uspLkp_DrugProductSelectAllByName]
(
    @PROPRIETARY_NAME varchar(10)
)
as
    set nocount on
    declare @PROPRIETARY_NAME2 varchar(10) = '"' + @PROPRIETARY_NAME + '*"'

    select ldp.*, lkp.DRUG_PKG_ID
    from Lkp_DrugProduct ldp
    left outer join Lkp_DrugPackage lkp on ldp.DRUG_PROD_ID = lkp.DRUG_PROD_ID
    where contains(ldp.PROPRIETARY_NAME, @PROPRIETARY_NAME2)

Quando se trata de pesquisa de texto completo, para meu dinheiro nada se compara Lucena.Existe um Porta .Net disponível que seja compatível com índices criados com a versão Java.

Há um pouco de trabalho envolvido na criação/manutenção dos índices, mas a velocidade de pesquisa é fantástica e você pode criar todos os tipos de consultas interessantes.Até a velocidade de indexação é muito boa - apenas reconstruímos completamente nossos índices uma vez por dia e não nos preocupamos em atualizá-los.

Como um exemplo, esta funcionalidade de pesquisa é alimentado por Lucene.Net.

Talvez o link a seguir forneça a resposta final para esse uso de curingas: Realizando pesquisas curinga FTS.

Observe a passagem que diz:"No entanto, se você especificar “Cadeia” ou “Chain”, você não obterá o resultado esperado.O asterisco será considerado um sinal de pontuação normal e não um caractere curinga."

Se você tiver acesso à lista de palavras do mecanismo de pesquisa de texto completo, poderá fazer uma pesquisa 'curtir' nesta lista e combinar o banco de dados com as palavras encontradas, por exemplo.uma tabela 'palavras' com as seguintes palavras:

    pie
    applepie
    spies
    cherrypie
    dog
    cat

Para combinar todas as palavras contendo 'torta' neste banco de dados em uma tabela fts 'full_text' com campo 'texto':

    to-match <- SELECT word FROM words WHERE word LIKE '%pie%'
    matcher = ""
    a = ""
    foreach(m, to-match) {
      matcher += a
      matcher += m
      a = " OR "
    }
    SELECT text FROM full_text WHERE text MATCH matcher

% Corresponde a qualquer número de caracteres _ corresponde a um único caractere

Nunca usei indexação de texto completo, mas você pode realizar consultas de pesquisa bastante complexas e rápidas simplesmente usando a construção em funções de string T-SQL.

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