Après quelques jours de travail intense, j'ai finalement mis en œuvre une simple recherche en texte intégral. Permettez-moi de revoir et de résumer
cet article. Qu'est-ce que Lucene.Net ? Que peut faire Lucene.Net ? Et la question de savoir comment faire ? Enfin, un exemple de Lucene.Net implémentant la recherche en texte intégral est donné.
1. Qu'est-ce que Lucene.Net ?
Lucene.net était à l'origine un projet open source, puis s'est tourné vers la commercialisation. Lucene.net 2.0 a également été publié, mais pour de l'argent D. Le sort de Lucene.net est quelque peu similaire à celui de FreeTextBox, qui a commencé avec la version 2.0 publiée après la version 1.6. 5. Voie commerciale, 2.0 fournit une version gratuite sous forme de DLL, et la version du code source doit acheter une licence commerciale, cependant, elle laisse le code source de la version 1.6.5, et vous pouvez toujours voir la plupart des détails internes ; , mais dans la version 2.0. La prise en charge supplémentaire du navigateur Mozilla n'est visible qu'à travers les scripts HTML et JavaScript qu'il génère.
Lucene est une API d'indexation couramment utilisée dans le monde Java. Grâce aux méthodes qu'elle fournit, vous pouvez créer des index pour les éléments textuels et assurer la récupération. (Référence : NLucene et Lucene .NET) NLucene est le premier port .net et une version de style .net qui utilise les conventions de dénomination .net et la conception de bibliothèques de classes. Cependant, pour des raisons énergétiques, le leader du projet NLucene n'a publié que la version 1.2beta. Après l'émergence du projet Lucene.NET, il n'y avait aucun nouveau projet pour NLucene.
Lucene.NET prétendait à l'origine être une greffe .net Lucene à jour. Il n'adoptait que les suggestions de .net en termes de dénomination. Ses principaux objectifs tendaient à être compatibles avec Java Lucene : l'un était de rendre le format d'index compatible afin que. ils pourraient fonctionner ensemble. Le premier objectif est que le nom soit proche (avec seulement quelques différences, telles que les majuscules et les minuscules, etc.), et le but est de faciliter l'utilisation du code et des informations liés à Java Lucene.
Je ne sais pas quand le projet Lucene.NET a abandonné son plan open source et s'est tourné vers les affaires. Il a en fait supprimé les fichiers open source sur SourceForge. Au même moment, le projet dotLucene est apparu sur SourceForge. En signe de protestation contre Lucene.NET, dotLucene a presque laissé intact le code de Lucene.NET comme point de départ. ( https://sourceforge.net/forum/forum.php?thread_id=1153933&forum_id=408004 ).
Pour parler franchement, Lucene.Net est une bibliothèque de fonctions de récupération d'informations (Bibliothèque). Vous pouvez l'utiliser pour ajouter des fonctions d'indexation et de recherche à votre application.
Les utilisateurs de Lucene n'ont pas besoin d'avoir des connaissances approfondies sur la récupération de texte intégral, mais. apprenez simplement à utiliser la bibliothèque. Si vous savez comment appeler les fonctions de la bibliothèque, vous pouvez réaliser la fonction de recherche en texte intégral pour votre application.
Mais ne vous attendez pas à ce que Lucene soit un moteur de recherche comme Google et Baidu. un outil, une bibliothèque. Vous pouvez également le considérer comme une API simple et facile à utiliser qui encapsule les fonctions d'indexation et de recherche. Vous pouvez faire beaucoup de choses liées à la recherche avec cette API, et elle est très pratique et peut. satisfaire vos besoins. Une application effectue une recherche simple en texte intégral. En tant que développeur d'applications (développeur de moteurs de recherche non professionnel), ses fonctionnalités suffisent à vous satisfaire.
2. Que peut faire Lucene.Net ?
Lucene peut indexer et rechercher n'importe quelle donnée, quel que soit le format de la source de données, à condition qu'elle puisse être convertie en texte, elle peut être analysée et utilisée par Lucene. En d'autres termes, qu'il s'agisse de MS Word, HTML, PDF ou. autre N'importe quelle forme de fichier peut être utilisée par Lucene à condition que vous puissiez en extraire le contenu textuel. Vous pouvez utiliser Lucene pour les indexer et les rechercher.
3. Comment utiliser Lucene.Net ?
Cela se résume simplement à : créer un index, et utiliser un index. Créer un index consiste à stocker ou analyser les informations de la source de données à rechercher comme informations clés, et laisser une marque pour la recherche, c'est comme créer un tableau de. contenu dans Word (compréhension personnelle), l'utilisation de l'index consiste à analyser la source de données en fonction des informations de l'index lors de la recherche et à extraire les informations dont nous avons besoin.
Veuillez jeter un œil à l'exemple :
classe publique IntranetIndexer
pour créer un index
{
/**/////Rédacteur d'index
private IndexWriterwriter ;
//Le répertoire racine du fichier à écrire dans l'index
chaîne privée docRootDirectory ;
//Format de fichier correspondant
modèle de chaîne privée[] ;
/**//// <résumé>
/// Initialise un rédacteur d'index. Le répertoire est le répertoire dans lequel l'index est créé. true signifie que si le fichier d'index n'existe pas, le fichier d'index sera recréé. Si le fichier d'index existe déjà, le fichier d'index sera recréé. écrasé.
/// </summary>
/// <param name="directory">Le répertoire à indexer est transmis. Notez qu'il s'agit d'une valeur de chaîne. Si le répertoire n'existe pas, il sera automatiquement créé</param>.
publicIntranetIndexer (répertoire de chaînes)
{
writer = new IndexWriter(répertoire, new StandardAnalyzer(), true);
écrivain.SetUseCompoundFile(true);
}
public void AddDirectory (répertoire DirectoryInfo, modèle de chaîne [])
{
this.docRootDirectory = répertoire.FullName;
this.motif = motif ;
addSubDirectory(répertoire);
}
private void addSubDirectory (répertoire DirectoryInfo)
{
pour(int i=0;i<motif .Length ;i++)
{
foreach (FileInfo fi dans le répertoire.GetFiles(pattern[i]))
{
AddHtmlDocument(fi.FullName);
}
}
foreach (DirectoryInfo dans directory.GetDirectories())
{
addSubDirectory(di);
}
}
public void AddHtmlDocument (chemin de chaîne)
{
string exname=Path.GetExtension (chemin);
Document doc = nouveau Document();
chaîne HTML ;
if(exname.ToLower ()==".html" ||exname .ToLower ()==".htm"||exname .ToLower ()==".txt")
{
using(StreamReader sr=new StreamReader (path,System .Text .Encoding .Default ))
{
html = sr.ReadToEnd();
}
}
autre
{
en utilisant (StreamReader sr = new StreamReader(path, System.Text.Encoding.Unicode ))
{
html = sr.ReadToEnd();
}
}
int relativePathStartsAt = this.docRootDirectory.EndsWith("\") ? this.docRootDirectory.Length : this.docRootDirectory.Length + 1;
chaîne relativePath = path.Substring(relativePathStartsAt);
titre de chaîne=Path.GetFileName(chemin);
//Déterminez s'il s'agit d'une page Web, supprimez la balise, sinon ne l'utilisez pas
if(exname.ToLower ()==".html" ||exname .ToLower ()==".htm")
{
doc.Add(Field.UnStored("text", parseHtml(html)));
}
autre
{
doc.Add (Champ .UnStored ("texte",html));
}
doc.Add(Field.Keyword("chemin", relativePath));
//doc.Add(Field.Text("titre", getTitle(html)));
doc.Add (Champ .Text ("titre", titre));
écrivain.AddDocument(doc);
}
/**//// <résumé>
/// Supprimer les balises des pages Web
/// </summary>
/// <param name="html">Page Web</param>
/// <returns>Renvoyer le texte de la page Web supprimé</returns>
chaîne privée parseHtml (chaîne html)
{
string temp = Regex.Replace(html, "<[^>]*>", "");
return temp.Replace(" ", " ");
}
/**//// <résumé>
/// Récupère le titre de la page
/// </summary>
/// <param name="html"></param>
/// <retours></retours>
chaîne privée getTitle (chaîne html)
{
Match m = Regex.Match(html, "<titre>(.*)</titre>");
si (m.Groups.Count == 2)
renvoyer m.Groups[1].Value ;
return "Titre du document inconnu" ;
}
/**//// <résumé>
/// Optimiser l'index et fermer le rédacteur
/// </summary>
public void Fermer()
{
écrivain.Optimize();
écrivain.Close();
}
}
Créez d'abord un objet Document, puis ajoutez quelques attributs Field à l'objet Document. Vous pouvez considérer l'objet Document comme un fichier virtuel, à partir duquel les informations seront obtenues à l'avenir. Le champ est considéré comme des métadonnées décrivant ce fichier virtuel. . Parmi eux, Field comprend quatre types : Keywork
Les données de ce type ne seront pas analysées, mais seront indexées et enregistrées dans l'index.
Non indexé
Les données de ce type ne seront ni analysées ni indexées, mais seront stockées dans l'index.
Non stocké
Contrairement à UnIndexed, il est analysé et indexé, mais pas enregistré.
Texte
Semblable à UnStored Si le type de valeur est une chaîne, il sera enregistré. Si le type de valeur est Reader, il ne sera pas enregistré, tout comme UnStored.
Enfin, chaque document est ajouté à l'index.
Ce qui suit est une recherche de l'index
//Créer un indexeur
Recherche IndexSearcher = new IndexSearcher (indexDirectory);
//Analyse le champ de texte de l'index pour la recherche
Requête de requête = QueryParser.Parse(this.Q, "text", new StandardAnalyzer());
//Mettre les résultats de la recherche dans les hits
Clics hits = searcher.Search(query);
//Statistiques sur le nombre total d'enregistrements recherchés
this.total = hits.Length();
//Souligner
Surligneur QueryHighlightExtractor = new QueryHighlightExtractor(query, new StandardAnalyzer(), "<font color=red>", "</font>");
La première étape consiste à utiliser IndexSearcher pour ouvrir le fichier d'index pour les recherches ultérieures, et le paramètre est le chemin du fichier d'index.
La deuxième étape consiste à utiliser QueryParser pour convertir des instructions de requête plus lisibles (telles que le mot de requête lucene, et certaines). méthodes avancées lucene AND. net) dans un objet de requête utilisé en interne par Lucene.
La troisième étape effectue la recherche et renvoie les résultats à la collection de hits. Il convient de noter que Lucene ne met pas tous les résultats dans des hits en même temps mais les met. partie à la fois. Pour des raisons d'espace,
les résultats de la recherche sont ensuite traités et affichés sur la page :
for (int i = startAt; i < resultsCount; i++)
{
Document doc = hits.Doc(i);
string chemin = doc.Get("chemin");
chaîne emplacement =Server.MapPath("documents")+" \"+chemin ;
string exname=Path.GetExtension (chemin);
chaîne texte brut ;
string str=doc.Get ("titre");
si(exname==".html" || exname ==".htm" || exname ==".txt")
{
en utilisant (StreamReader sr = new StreamReader (emplacement, System.Text.Encoding.Default))
{
plainText = parseHtml(sr.ReadToEnd());
}
}
autre
{
en utilisant (StreamReader sr = new StreamReader(location, System.Text.Encoding.Unicode ))
{
plainText = sr.ReadToEnd();
}
}
//DataTable ajoute des lignes
Ligne DataRow = this.Results.NewRow();
row["titre"] = doc.Get("titre");
string IP=Request.Url.Host;//Obtenir l'IP du serveur
//Demande.Url.Port;
row["chemin"]=@" http://"+IP+"/WebUI/Search/documents/"+chemin ;
row["sample"] = highlighter.GetBestFragments(plainText, 80, 2, "");
this.Results.Rows.Add(ligne);
}
searcher.Close();//Fermez le moteur de recherche Si vous souhaitez avoir une compréhension plus avancée, complète et approfondie de Lucene.Net, veuillez vous référer au site Web :
http : //blog.tianya.cn/blogger/view_blog.asp?BlogName=aftaft