Comment faire pour que les recherches en texte intégral avec caractères génériques fonctionnent dans SQL Server?
Remarque: I suis en utilisant les capacités de recherche de texte intégral de SQL, contient des clauses et tout-le * est le Joker en texte intégral, le % est réservé aux clauses similaires.
j'ai lu à plusieurs endroits maintenant que les recherches de "leading wildcard" (par exemple en utilisant "*overflow" pour correspondre à "stackoverflow") ne sont pas supportées dans MS SQL. Je suis en train d'étudier à l'aide d'un fonction CLR pour ajouter l'expression rationnelle correspondant à, mais je suis curieux de voir quelles autres solutions les gens pourraient avoir.
Plus D'Info:Vous pouvez ajouter l'astérisque à la fin du mot ou de la phrase. - ainsi que mon expérience empirique: Lors de l'appariement des "mavaleur", "mon*" œuvres", mais "(astérisque)" ne retourne aucun match, lors d'une requête aussi simple que:
SELECT * FROM TABLENAME WHERE CONTAINS(TextColumn, '"*searchterm"');
ainsi, mon besoin d'une solution de contournement. J'utilise seulement la recherche dans mon site sur une page de recherche réelle - donc il doit fonctionner essentiellement de la même façon que Google fonctionne (dans les yeux sur un Joe Sixpack-type utilisateur.) Pas aussi compliqué, mais ce genre de match ne devrait pas échouer.
14 réponses
contournement seulement pour les caractères génériques:
- stocker le texte inversé dans un champ différent (ou en vue matérialisée)
- créer un index de texte intégral sur cette colonne
trouver le texte inversé avec un *
SELECT * FROM TABLENAME WHERE CONTAINS(TextColumnREV, '"mrethcraes*"');
bien sûr, il y a beaucoup d'inconvénients, juste pour contourner rapidement...
sans mentionner CONTAINSTABLE...
le problème avec les caractères génériques: ils ne peuvent pas être indexés, donc vous faites un balayage complet de la table.
par exemple, cette requête va trouver tous les "Database", "database", "databases" ...
SELECT * FROM SomeTable WHERE CONTAINS(ColumnName, '"datab*"')
mais, malheureusement, il n'est pas possible de rechercher avec le Joker principal.
par exemple, cette requête ne trouvera pas"database"
SELECT * FROM SomeTable WHERE CONTAINS(ColumnName, '"*abase"')
pour peut-être ajouter de la clarté à ce fil, de mes essais sur 2008 R2, Franjo est correct ci-dessus. Lors de la recherche en texte intégral, au moins lorsque vous utilisez la phrase CONTAINS, vous ne pouvez pas utiliser un, seulement une fuite fonctionnellement. * le générique, pas % en texte intégral.
Certains ont suggéré que * est ignoré. Cela ne semble pas être le cas, mes résultats semblent montrer que la fonctionnalité de suivi * fonctionne. Je pense que les leaders * sont ignorés par le moteur.
mon problème ajouté cependant est que la même requête, avec un * de suivi, qui utilise le texte intégral avec des caractères génériques a fonctionné relativement vite sur 2005(20 secondes), et a ralenti à 12 minutes après avoir migré le db vers 2008 R2. Il semble qu'au moins un autre utilisateur a eu des résultats similaires et il a commencé un forum post que j'ai ajouté... Le FREETEXT fonctionne encore rapidement, mais quelque chose" semble " avoir changé avec la façon dont les processus de 2008 * en contient. Ils donnent toutes sortes d'avertissements dans la mise à niveau Conseil qu'ils ont "amélioré" le texte complet pour que votre code puisse casser, mais malheureusement ils ne vous donnent pas d'avertissements spécifiques au sujet de certains codes dépréciés, etc. ...juste un avertissement qu'ils ont changé, utilisez à vos propres risques.
http://social.msdn.microsoft.com/Forums/ar-SA/sqlsearch/thread/7e45b7e4-2061-4c89-af68-febd668f346c
peut-être, il s'agit de la MS hit la plus proche liée à ces questions... http://msdn.microsoft.com/en-us/library/ms143709.aspx
une chose qui vaut la peine de garder à l'esprit est que les requêtes de caractères génériques de premier plan ont une prime de performance significative, par rapport aux autres utilisations de caractères génériques.
le caractère de Joker dans SQL Server est le %
signe et il fonctionne très bien, conduisant, de fuite ou autre.
cela dit, si vous devez effectuer une recherche sérieuse en texte intégral, alors j'envisagerais d'utiliser les capacités D'Index en texte intégral. En utilisant %
et _
les wild cards vont donner un sérieux coup de pouce à votre base de données.
From SQL Server Books Online:
Pour écrire des requêtes de texte intégral dans Microsoft SQL Server 2005, vous devez apprendre à utiliser le contenu et FREETEXT Transact-SQL prédit, et le CONTAINSTABLE et FREETEXTTABLE ensemble de lignes de fonctions dont la valeur est.
cela signifie que toutes les requêtes écrites ci-dessus avec le % et _ ne sont pas des requêtes en texte intégral valides.
voici un exemple de ce à quoi ressemble une requête lors de l'appel du CONTAINSTABLE fonction.
SELECT RANK, * FROM TableName , CONTAINSTABLE (TableName,*," "*Joker"') searchTable WHERE [Clé] = TableName.PK ordre par searchTable.GRADE DESC
pour que la fonction CONTAINSTABLE sache que j'utilise une recherche de jokers, je dois l'envelopper de guillemets. Je peux utiliser le caractère * au début ou à la fin. Il y a beaucoup d'autres choses que vous pouvez faire quand vous construisez la recherche string pour la fonction CONTAINSTABLE. Vous pouvez rechercher un mot près d'un autre mot, rechercher des mots d'ordre (drive = drives, driven, driving, and driven), et rechercher un synonyme d'un autre mot (le métal peut avoir des synonymes tels que l'aluminium et l'acier).
je viens de créer une table, j'ai mis un index texte complet sur la table et j'ai fait quelques recherches de test et je n'ai pas eu de problème, donc la recherche par caractère générique fonctionne comme prévu.
[mise à Jour]
je vois que vous avez mis à jour votre question et de savoir que vous devez utiliser l'une des fonctions.
Vous pouvez toujours rechercher avec le caractère générique au début, mais si le mot n'est pas un mot complet suivant le générique, vous devez ajouter un autre joker à la fin.
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.]
[mise à Jour #2]
Dave Ward-L'utilisation d'un joker avec l'une des fonctions ne devrait pas être un énorme succès. Si j'ai créé une chaîne de recherche avec juste"*", elle ne retournera pas toutes les lignes, dans mon cas de test, elle retournera 0 dossier.
juste pour info, Google ne fait pas de recherches de sous-chaînes ou de troncature, à droite ou à gauche. Ils ont un caractère générique * pour trouver les mots inconnus dans une phrase, mais pas un mot.
Google, avec la plupart des moteurs de recherche plein texte, met en place un index inversé basé sur l'ordre alphabétique des mots, avec des liens vers leurs documents sources. La recherche binaire est très rapide, même pour des index énormes. Mais il est vraiment très difficile de faire une troncature à gauche dans ce cas, parce qu'il perd le l'avantage de l'index.
Comme paramètre dans une procédure stockée, vous pouvez l'utiliser comme:
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)
quand il s'agit de la recherche plein texte, pour mon argent rien ne bat Lucene. Il y a un .net port disponible compatible avec les index créés avec la version Java.
il y a un peu de travail que vous devez faire pour créer/maintenir les index, mais la vitesse de recherche est fantastique et vous pouvez créer toutes sortes de requêtes intéressantes. Même la vitesse d'indexation est assez bonne - nous reconstruisons complètement nos Index une fois par jour et ne vous inquiétez pas à propos de la mise à jour.
par exemple, cette fonctionnalité de recherche
peut-être le lien suivant fournira la réponse à cette utilisation de caractères génériques: effectuer des recherches de caractères génériques FTS.
Notez le passage suivant: "However, if you specify" chaîne " ou " Chain", vous n'obtiendrez pas le résultat escompté. L'astérisque sera considéré comme un signe de ponctuation pas un caractère générique. "
si vous avez accès à la liste des mots du moteur de recherche plein texte, vous pouvez faire une recherche 'j'aime' sur cette liste et faire correspondre la base de données avec les mots trouvés, par exemple un tableau 'mots' avec les mots suivants:
pie
applepie
spies
cherrypie
dog
cat
pour apparier tous les mots contenant 'pie' dans cette base de données sur une table fts 'full_text' avec le champ 'text':
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
% correspond à n'importe quel nombre de caractères _ Correspond à un caractère unique
Je n'ai jamais utilisé l'indexation plein texte mais vous pouvez accomplir des requêtes de recherche plutôt complexes et rapides en utilisant simplement la construction dans les fonctions de chaîne de caractères T-SQL.
en utilisant le caractère ' % ' j'ai cherché dans notre base de données en utilisant quelque chose comme ceci:
SELECT name FROM TblNames WHERE name LIKE '%overflow'
L'utilisation de cette forme ou requête peut être lente à certains moments, mais nous ne l'utilisons que pour la recherche manuelle occasionnelle.