c# - usar - sql buscar dentro de una cadena
¿Qué tan difícil es incorporar la búsqueda de texto completo con SQL Server? (5)
Estoy construyendo una aplicación C # / ASP.NET con un back-end SQL. Estoy en la fecha límite y estoy terminando mis páginas, fuera del campo izquierdo uno de mis diseñadores incorporó una búsqueda de texto completo en una de mis páginas. Mis "búsquedas" hasta este momento han sido filtros, pudiendo restringir un conjunto de resultados por ciertos factores y valores de columna.
Siendo que estoy en la fecha límite (sabes 3 horas de sueño por noche, en el punto en que parezco algo que el gato comió y vomitó), esperaba que esta página fuera muy similar a otras y estoy intentando para decidir si apestar o no. Nunca antes había hecho una búsqueda de texto completo en una página ... ¿es una montaña para escalar o hay una solución simple?
gracias.
"¿Qué tan difícil es?" Es una pregunta difícil de responder. Por ejemplo, alguien que ya lo ha hecho 10 veces probablemente piense que es muy fácil. Todo lo que puedo decir es que es probable que te resulte mucho más fácil si utilizas algo como NLucene en lugar de hacer tu propio.
En primer lugar, debe habilitar el texto completo Búsqueda de indexación en los servidores de producción, de modo que, si no está dentro del alcance, no va a querer ir con esto.
Sin embargo, si eso ya está listo, la búsqueda de texto completo es relativamente simple.
T-SQL tiene 4 predicados utilizados para la búsqueda de texto completo:
- TEXTO LIBRE
- FREETEXTTABLE
- CONTIENE
- CONTAINSTABLE
FREETEXT es el más simple, y se puede hacer así:
SELECT UserName
FROM Tbl_Users
WHERE FREETEXT (UserName, ''bob'' )
Results:
JimBob
Little Bobby Tables
FREETEXTTABLE funciona igual que FreeTEXT, excepto que devuelve los resultados como una tabla.
El verdadero poder de la búsqueda de texto completo de T-SQL proviene del predicado CONTAINS (y CONTAINSTABLE) ... Este es enorme, así que simplemente pegaré su uso en:
CONTAINS
( { column | * } , ''< contains_search_condition >''
)
< contains_search_condition > ::=
{ < simple_term >
| < prefix_term >
| < generation_term >
| < proximity_term >
| < weighted_term >
}
| { ( < contains_search_condition > )
{ AND | AND NOT | OR } < contains_search_condition > [ ...n ]
}
< simple_term > ::=
word | " phrase "
< prefix term > ::=
{ "word * " | "phrase * " }
< generation_term > ::=
FORMSOF ( INFLECTIONAL , < simple_term > [ ,...n ] )
< proximity_term > ::=
{ < simple_term > | < prefix_term > }
{ { NEAR | ~ } { < simple_term > | < prefix_term > } } [ ...n ]
< weighted_term > ::=
ISABOUT
( { {
< simple_term >
| < prefix_term >
| < generation_term >
| < proximity_term >
}
[ WEIGHT ( weight_value ) ]
} [ ,...n ]
)
Esto significa que puede escribir consultas tales como:
SELECT UserName
FROM Tbl_Users
WHERE CONTAINS(UserName, ''"little*" NEAR tables'')
Results:
Little Bobby Tables
Buena suerte :)
He usado dtSearch antes para agregar búsquedas de texto completo a archivos y bases de datos, y sus cosas son bastante baratas y fáciles de usar.
Además de agregar todo eso y configurar SQL, este script buscará en todas las columnas de una base de datos y le dirá qué columnas contienen los valores que está buscando. Sé que no es la solución "adecuada", pero puede que le compre algo de tiempo.
/*This script will find any text value in the database*/
/*Output will be directed to the Messages window. Don''t forget to look there!!!*/
SET NOCOUNT ON
DECLARE @valuetosearchfor varchar(128), @objectOwner varchar(64)
SET @valuetosearchfor = ''%staff%'' --should be formatted as a like search
SET @objectOwner = ''dbo''
DECLARE @potentialcolumns TABLE (id int IDENTITY, sql varchar(4000))
INSERT INTO @potentialcolumns (sql)
SELECT
(''if exists (select 1 from ['' +
[tabs].[table_schema] + ''].['' +
[tabs].[table_name] +
''] (NOLOCK) where ['' +
[cols].[column_name] +
''] like '''''' + @valuetosearchfor + '''''' ) print ''''SELECT * FROM ['' +
[tabs].[table_schema] + ''].['' +
[tabs].[table_name] +
''] (NOLOCK) WHERE ['' +
[cols].[column_name] +
''] LIKE '''''''''' + @valuetosearchfor + '''''''''''' +
'''''''') as ''sql''
FROM information_schema.columns cols
INNER JOIN information_schema.tables tabs
ON cols.TABLE_CATALOG = tabs.TABLE_CATALOG
AND cols.TABLE_SCHEMA = tabs.TABLE_SCHEMA
AND cols.TABLE_NAME = tabs.TABLE_NAME
WHERE cols.data_type IN (''char'', ''varchar'', ''nvchar'', ''nvarchar'',''text'',''ntext'')
AND tabs.table_schema = @objectOwner
AND tabs.TABLE_TYPE = ''BASE TABLE''
ORDER BY tabs.table_catalog, tabs.table_name, cols.ordinal_position
DECLARE @count int
SET @count = (SELECT MAX(id) FROM @potentialcolumns)
PRINT ''Found '' + CAST(@count as varchar) + '' potential columns.''
PRINT ''Beginning scan...''
PRINT ''''
PRINT ''These columns contain the values being searched for...''
PRINT ''''
DECLARE @iterator int, @sql varchar(4000)
SET @iterator = 1
WHILE @iterator <= (SELECT Max(id) FROM @potentialcolumns)
BEGIN
SET @sql = (SELECT [sql] FROM @potentialcolumns where [id] = @iterator)
IF (@sql IS NOT NULL) and (RTRIM(LTRIM(@sql)) <> '''')
BEGIN
--SELECT @sql --use when checking sql output
EXEC (@sql)
END
SET @iterator = @iterator + 1
END
PRINT ''''
PRINT ''Scan completed''
La búsqueda de texto completo en SQL Server es muy fácil, un poco de configuración y un ligero ajuste en la consulta y ¡listo! Lo he hecho por clientes en menos de 20 minutos antes, estoy familiarizado con el proceso
Aquí está el artículo de MSDN 2008 , los enlaces salen a las versiones de 2005 desde allí
He estado allí. Funciona como un amuleto hasta que comienza a considerar la escalabilidad y funcionalidades de búsqueda avanzada como la búsqueda en múltiples columnas, dando a cada uno diferentes valores de peso.
Por ejemplo, la única forma de buscar columnas de Título y Resumen es tener una columna calculada con SearchColumn = CONCAT(Title, Summary)
e indexar sobre SearchColumn
. ¿Ponderación? SearchColumn = CONCAT(CONCAT(Title,Title), Summary)
algo así. ;) Filtrado? Olvídalo.