2008-08-06 29 views
31

Nota: I am usando las capacidades de búsqueda de texto completo de SQL, cláusulas CONTAINS y todo - el * es el comodín en texto completo,% es solo para cláusulas MEJORAS.¿Cómo se obtienen las búsquedas de texto completo con comodín para trabajar en SQL Server?

He leído en varios lugares ahora que las búsquedas de "comodín principal" (por ejemplo, utilizando "* overflow" para que coincida con "stackoverflow") no son compatibles con MS SQL. Estoy considerando usar un CLR function to add regex matching, pero tengo curiosidad por ver qué otras soluciones podrían tener las personas.

Más información: You can add the asterisk only at the end of the word or phrase. - junto con mi experiencia empírica: Cuando juego "mivalor", "mi *" funciona, pero "(asterisco) Valor" devuelve ninguna coincidencia, cuando se hace una consulta tan simple como:

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

Por lo tanto, mi necesidad de una solución alternativa. Solo estoy usando la búsqueda en mi sitio en una página de búsqueda real, por lo que debe funcionar básicamente de la misma manera que funciona Google (a los ojos de un usuario tipo Joe Sixpack). No es tan complicado, pero este tipo de partido no debería fallar.

Respuesta

2

El carácter comodín en SQL Server es el signo % y funciona bien, avanzando, al final o de lo contrario.

Dicho esto, si va a hacer algún tipo de búsqueda seria de texto completo, entonces consideraría utilizar las capacidades del Índice de texto completo. El uso de comodines % y _ hará que su base de datos tenga un impacto de rendimiento serio.

0

% Coincide con cualquier número de caracteres _ coincide con un solo carácter

nunca he utilizado la indexación de texto completo, sino que se pueden realizar consultas de búsqueda más complejos y rápidos con el simple uso de la estructura en funciones de cadena de T-SQL .

4

Una cosa que vale la pena tener en cuenta es que las consultas con comodines líderes tienen un rendimiento premium significativo, en comparación con otros usos comodín.

15

El problema con los comodines principales: no se pueden indexar, por lo tanto, se está haciendo un escaneo completo de la tabla.

-1

Utilizando el carácter '%' He buscado en nuestra base de datos utilizando algo como lo siguiente:

SELECT name FROM TblNames WHERE name LIKE '%overflow' 

El uso de este formulario o la consulta puede ser lento a veces, pero que sólo lo uso para la búsqueda manual de vez en cuando.

1

De SQL Server Books Online:

Para escribir consultas de texto en Microsoft SQL Server 2005, debe aprender cómo utilizar la contiene y FREETEXT predicados de Transact-SQL, y la CONTAINSTABLE y FREETEXTTABLE funciones con valores de conjunto de filas.

Eso significa que todas las consultas escritas arriba con% y _ no son consultas válidas de texto completo.

Aquí hay un ejemplo de cómo se ve una consulta cuando se llama a la función CONTAINSTABLE.

RANK SELECT, * FROM TableName, CONTAINSTABLE (TableName, *, ' "comodín *"') searchTable DONDE [KEY] = TableName.pk ORDER BY searchTable.RANK DESC

Para que la función CONTAINSTABLE sepa que estoy usando una búsqueda comodín, debo envolverla entre comillas dobles. Puedo usar el carácter comodín * al principio o al final. Hay muchas otras cosas que puede hacer cuando construye la cadena de búsqueda para la función CONTAINSTABLE. Puede buscar una palabra cerca de otra palabra, buscar palabras de inflexión (conducir = conducir, conducir, conducir) y buscar sinónimo de otra palabra (el metal puede tener sinónimos como el aluminio y el acero).

Acabo de crear una tabla, poner un índice de texto completo en la tabla e hice un par de búsquedas de prueba y no tuve ningún problema, por lo que la búsqueda de comodines funciona según lo previsto.

[Actualización]

veo que has actualizado tu pregunta y saber que es necesario utilizar una de las funciones.

Todavía puede buscar con el comodín al principio, pero si la palabra no es una palabra completa siguiendo el comodín, tiene que agregar otro comodín al 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.] 

[Actualización # 2]

Dave Ward - El uso de un comodín con una de las funciones no debería ser un gran éxito perf. Si creé una cadena de búsqueda con solo "*", no devolverá todas las filas, en mi caso de prueba, devolvió 0 registros.

+0

No puedo reproducir esto en SQL 2005. Usar un * en la parte delantera de la cadena de búsqueda como se muestra no genera filas. – gregmac

+15

No estoy seguro de por qué esto está marcado como la respuesta, porque no es completamente exacto. ** El el comodín principal no funciona en una búsqueda de texto completo. ** Verificó esto en SQL Server 2008 en un índice de texto completo usando la función de contenido estable. Consulte la respuesta/publicación de Michael Stum para comprender por qué. – Jagd

+0

@Jagd - Proporcione una respuesta mejor luego –

0

Cuando se trata de búsqueda de texto completo, para mi dinero nada supera a Lucene. Hay un .Net port available que es compatible con índices creados con la versión de Java.

Hay un poco de trabajo involucrado en que tiene que crear/mantener los índices, pero la velocidad de búsqueda es fantástica y puede crear todo tipo de consultas interesantes. Incluso la velocidad de indexación es bastante buena: reconstruimos completamente nuestros índices una vez al día y no nos preocupamos por actualizarlos. Por ejemplo, this search functionality es alimentado por Lucene.Net.

1

Solo para su información, Google no realiza ninguna búsqueda de subcadenas ni truncamiento, derecha o izquierda. Tienen un carácter comodín * para encontrar palabras desconocidas en una frase, pero no una palabra.

Google, junto con la mayoría de los motores de búsqueda de texto completo, establece un índice invertido basado en el orden alfabético de las palabras, con enlaces a sus documentos de origen. La búsqueda binaria es muy rápida, incluso para índices enormes. Pero es realmente muy difícil hacer un truncamiento de la izquierda en este caso, porque pierde la ventaja del índice.

19

solución sólo para comodín líder:

  • almacenar el texto invertido en un campo diferente (o en la vista materializada)
  • crear un índice de texto completo en esta columna
  • encuentra el texto invertido con * un

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

Por supuesto, hay ar e muchos inconvenientes, sólo para solución rápida ...

no hablar de CONTAINSTABLE ...

4

Es posible utilizar el comodín "*" al final de la palabra o frase (búsqueda prefijo).

Por ejemplo, esta consulta encontrará todos "datab", "base de datos", "bases de datos" ...

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

Pero, unforutnately, no es posible realizar búsquedas con los principales comodín.

Por ejemplo, esta consulta no se encuentra "base de datos"

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

Hice bastantes búsquedas para esto, y lamentablemente, la mayoría de las personas están equivocadas y creen que pueden hacer una búsqueda comodín líder. Una búsqueda comodín líder no funciona. Franjo tiene razón, el comodín debe estar al final de la frase de búsqueda. Estoy usando SQL 2008 R2. No lo encuentra en absoluto (no hace una tabla o exploración de índice y lo encuentra, no lo encontrará en absoluto) – astrosteve

4

Para quizás añadir claridad a este tema, a partir de mis pruebas en 2008 R2, Franjo es correcta arriba. Cuando se trata de la búsqueda de texto completo, al menos cuando se utiliza la frase CONTAINS, no se puede usar un líder, solo un posterior funcionalmente. * es el comodín, no% en texto completo.

Algunos han sugerido que * se ignore. Ese no parece ser el caso, mis resultados parecen mostrar que la funcionalidad final * funciona. Creo que los principales * son ignorados por el motor.

Sin embargo, mi problema añadido es que la misma consulta, con un * final, que utiliza texto completo con comodines trabajó relativamente rápido en 2005 (20 segundos) y disminuyó a 12 minutos después de migrar el db a 2008 R2. Parece que al menos otro usuario tuvo resultados similares y comenzó una publicación en el foro que agregué a ... FREETEXT funciona todavía de manera rápida, pero algo "parece" haber cambiado con la forma en que los procesos 2008 siguen * en CONTIENE. Dan todo tipo de advertencias en el Asesor de actualizaciones de que "mejoraron" el TEXTO COMPLETO para que tu código se rompa, pero desafortunadamente no te dan advertencias específicas sobre ciertos códigos en desuso, etc. ... solo un descargo de responsabilidad que lo cambiaron, Úselo bajo su propio riesgo.

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

Tal vez, este es el más cercano MS golpe relacionado con estos temas ... http://msdn.microsoft.com/en-us/library/ms143709.aspx

1

como un parámetro en un procedimiento almacenado que se puede utilizar 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) 
0

Tal vez El siguiente enlace proporcionará la respuesta final a este uso de comodines: Performing FTS Wildcard Searches.

Nota del pasaje que dice: "Sin embargo, si especifica‘cadena’o‘Ch ain’, que no va a obtener el resultado esperado El asterisco será considerado como un signo de puntuacion normal no un carácter comodín.."

Cuestiones relacionadas