Depois de alguns dias de trabalho intenso, finalmente implementei uma pesquisa simples de texto completo. Deixe-me revisar e resumir
este artigo. O que Lucene.Net pode fazer? E a questão de como fazer isso? Finalmente, é dado um exemplo de Lucene.Net implementando pesquisa de texto completo.
1. O que é Lucene.Net?
Lucene.net era originalmente um projeto de código aberto e depois voltado para comercialização. Lucene.net 2.0 também foi lançado, mas por dinheiro D. O destino de Lucene.net é um pouco semelhante ao FreeTextBox, que começou com 2.0 lançado após a versão 1.6. 5. Rota comercial, 2.0 fornece uma versão gratuita na forma de DLL, e a versão do código-fonte deve adquirir uma licença comercial, porém, deixa o código-fonte da versão 1.6.5, e você ainda pode ver a maioria dos detalhes internos; , mas na versão 2.0 o suporte adicionado para o navegador Mozilla só é visível através dos scripts HTML e JavaScript que ele gera.
Lucene é uma API de indexação comumente usada no mundo Java. Usando os métodos que ela fornece, você pode criar índices para materiais de texto e fornecer recuperação. (Referência: NLucene e Lucene .NET) NLucene é o primeiro porte .net e uma versão estilo .net que usa convenções de nomenclatura .net e design de biblioteca de classes. Porém, por motivos energéticos, o líder do projeto NLucene lançou apenas a versão 1.2beta. Após o surgimento do projeto Lucene.NET, não houve novos planos para o NLucene.
Lucene.NET originalmente afirmava ser um transplante .net Lucene atualizado. Ele apenas adotou as sugestões do .net em termos de nomenclatura. Seus principais objetivos tendiam a ser compatíveis com Java Lucene: um era tornar o formato do índice compatível para que. eles poderiam trabalhar juntos;
Não sei quando o projeto Lucene.NET desistiu de seu plano de código aberto e voltou-se para os negócios. Na verdade, ele excluiu os arquivos de código aberto do SourceForge. Ao mesmo tempo, o projeto dotLucene apareceu no SourceForge. Em protesto contra o Lucene.NET, o dotLucene quase colocou o código Lucene.NET intacto como ponto de partida. ( https://sourceforge.net/forum/forum.php?thread_id=1153933&forum_id=408004 ).
Para ser franco, Lucene.Net é uma biblioteca de funções de recuperação de informações (Biblioteca). Você pode usá-la para adicionar funções de indexação e pesquisa ao seu aplicativo.
Os usuários do Lucene não precisam ter conhecimento profundo sobre recuperação de texto completo. apenas aprenda a usar a biblioteca. Se você souber como chamar as funções da Biblioteca, poderá realizar a função de pesquisa de texto completo para seu aplicativo.
Mas não espere que o Lucene seja um mecanismo de pesquisa como o Google e o Baidu. uma ferramenta, uma biblioteca. Você também pode pensar nisso como uma API simples e fácil de usar que encapsula funções de indexação e pesquisa. Você pode fazer muitas coisas relacionadas à pesquisa com essa API, e é muito conveniente e pode. satisfazer suas necessidades. Um aplicativo executa uma pesquisa simples de texto completo Como desenvolvedor de aplicativos (desenvolvedor de mecanismo de pesquisa não profissional), suas funções são suficientes para satisfazê-lo.
2. O que a Lucene.Net pode fazer?
O Lucene pode indexar e pesquisar qualquer dado independente do formato da fonte de dados, desde que possa ser convertido em texto, pode ser analisado e utilizado pelo Lucene.
outro Qualquer formato de arquivo pode ser usado pelo Lucene,
desde que você possa extrair conteúdo de texto dele. Você pode usar o Lucene para indexá-los e pesquisá-los.
Tudo se resume a: criar um índice e usar um índice Criar um índice é armazenar ou analisar as informações da fonte de dados a serem pesquisadas como nossas principais informações, e deixar uma marca para a pesquisa é como criar uma tabela de. conteúdo em Word (compreensão pessoal), usar o índice é analisar a fonte de dados com base nas informações do índice durante a pesquisa e extrair as informações que precisamos.
Por favor, dê uma olhada no exemplo:
classe pública IntranetIndexer
para criar um índice
{
/**/////Escritor de índice
private IndexWriter escritor;
//O diretório raiz do arquivo a ser gravado no índice
private string docRootDirectory;
//Formato de arquivo correspondente
padrão de string privada[]
/**//// <resumo>
/// Inicializar um gravador de índice. Diretório é o diretório onde o índice é criado. true significa que se o arquivo de índice não existir, o arquivo de índice será recriado. sobrescrito.
/// </sumário>
/// <param name="directory">O diretório a ser indexado é passado. Observe que é um valor de string. Se o diretório não existir, ele será criado automaticamente</param>.
publicIntranetIndexer(diretório de string)
{
escritor = novo IndexWriter(diretório, novo StandardAnalyzer(), verdadeiro);
escritor.SetUseCompoundFile(true);
}
public void AddDirectory (diretório DirectoryInfo, padrão string [])
{
this.docRootDirectory = diretório.NomeCompleto;
este.padrão = padrão;
addSubDirectory(diretório);
}
private void addSubDirectory (diretório DirectoryInfo)
{
for(int i=0;i<padrão .Comprimento ;i++)
{
foreach (FileInfo fi no diretório.GetFiles(pattern[i]))
{
AddHtmlDocument(fi.NomeCompleto);
}
}
foreach (DirectoryInfo em directory.GetDirectories())
{
addSubDiretório(di);
}
}
public void AddHtmlDocument(caminho da string)
{
string exname=Path.GetExtension (caminho);
Documento doc = new Documento();
stringhtml;
if(exname.ToLower ()==".html" ||exname .ToLower ()==".htm"||exname .ToLower ()==".txt")
{
usando(StreamReader sr=new StreamReader (caminho,System .Text .Encoding .Default ))
{
html = sr.ReadToEnd();
}
}
outro
{
usando (StreamReader sr = new StreamReader(caminho, System.Text.Encoding.Unicode ))
{
html = sr.ReadToEnd();
}
}
int relativoPathStartsAt = this.docRootDirectory.EndsWith("\") ? this.docRootDirectory.Length : this.docRootDirectory.Length + 1;
string relativoPath = path.Substring(relativePathStartsAt);
string title=Path.GetFileName(caminho);
//Determine se é uma página web, remova a tag, caso contrário não a utilize
if(exname.ToLower ()==".html" ||exname .ToLower ()==".htm")
{
doc.Add(Field.UnStored("texto", parseHtml(html)));
}
outro
{
doc.Add (Campo .UnStored ("texto",html));
}
doc.Add(Field.Keyword("caminho", relativoPath));
//doc.Add(Field.Text("título", getTitle(html)));
doc.Add (Campo .Text ("título",título));
escritor.AddDocument(doc);
}
/**//// <resumo>
/// Remove tags de páginas da web
/// </sumário>
/// <param name="html">Página da Web</param>
/// <returns>Retorna o texto removido da página da web</returns>
string privada parseHtml(string html)
{
string temp = Regex.Replace(html, "<[^>]*>", "");
return temp.Replace(" ", " ");
}
/**//// <resumo>
/// Obtém o título da página
/// </sumário>
/// <param name="html"></param>
/// <retorna></retorna>
string privada getTitle(string html)
{
Corresponder m = Regex.Match(html, "<title>(.*)</title>");
if (m.Groups.Count == 2)
retornar m.Grupos[1].Valor;
return "Título do documento desconhecido";
}
/**//// <resumo>
/// Otimiza o índice e fecha o gravador
/// </sumário>
público vazio Fechar()
{
escritor.Optimize();
escritor.Fechar();
}
}
Primeiro crie um objeto Document e depois adicione alguns atributos Field ao objeto Document Você pode pensar no objeto Document como um arquivo virtual, do qual as informações serão obtidas no futuro. O Field é considerado como metadados que descrevem esse arquivo virtual. . Entre eles, o campo inclui quatro tipos: Keywork
Dados deste tipo não serão analisados, mas serão indexados e salvos no índice.
Não indexado
Dados deste tipo não serão analisados ou indexados, mas serão armazenados no índice.
Não armazenado
Exatamente o oposto de UnIndexed, é analisado e indexado, mas não salvo.
Texto
Semelhante a UnStored. Se o tipo de valor for string, ele será salvo. Se o tipo de valor for Reader, ele não será salvo, assim como UnStored.
Finalmente, cada Documento é adicionado ao índice.
A seguir está uma pesquisa do índice
//Cria um indexador
Pesquisador IndexSearcher = novo IndexSearcher (indexDirectory);
//Analisa o campo de texto do índice para pesquisa
Consulta consulta = QueryParser.Parse(this.Q, "texto", new StandardAnalyzer());
//Coloque os resultados da pesquisa em hits
Acertos acertos = searcher.Search(query);
//Estatísticas sobre o número total de registros pesquisados
this.total = hits.Length();
//Destaque
Marcador QueryHighlightExtractor = new QueryHighlightExtractor(query, new StandardAnalyzer(), "<font color=red>", "</font>");
A primeira etapa é usar IndexSearcher para abrir o arquivo de índice para pesquisas subsequentes, e o parâmetro é o caminho do arquivo de índice.
A segunda etapa é usar QueryParser para converter instruções de consulta mais legíveis (como a palavra de consulta lucene e algumas). métodos avançados lucene AND. net) em um objeto de consulta usado internamente pelo Lucene
A terceira etapa realiza a pesquisa e retorna os resultados para a coleção de hits. Deve-se observar que Lucene não coloca todos os resultados em hits de uma vez, mas os coloca. parte de cada vez. Por questões de espaço,
os resultados da pesquisa são então processados e exibidos na página:
for (int i = startAt; i < resultsCount; i++)
{
Documento doc = hits.Doc(i);
string path = doc.Get("caminho
string location =Server.MapPath("documentos")+" \"+path ;
string exname=Path.GetExtension (caminho);
string texto simples;
string str=doc.Get ("título");
if(exnome==".html" || exnome ==".htm" || exnome ==".txt")
{
usando (StreamReader sr = novo StreamReader (localização, System.Text.Encoding.Default))
{
plainText = parseHtml(sr.ReadToEnd());
}
}
outro
{
usando (StreamReader sr = new StreamReader(localização, System.Text.Encoding.Unicode ))
{
plainText = sr.ReadToEnd();
}
}
//DataTable adiciona linhas
Linha DataRow = this.Results.NewRow();
linha["título"] = doc.Get("título");
string IP=Request.Url.Host;//Obtém o IP do servidor
//Request.Url.Port;
linha["caminho"]=@" http://"+IP+"/WebUI/Search/documents/"+caminho ;
linha["amostra"] = marcador.GetBestFragments(plainText, 80, 2, "");
this.Results.Rows.Add(linha);
}
searcher.Close();//Fecha o buscador. Se você deseja ter uma compreensão mais avançada, abrangente e aprofundada do Lucene.Net, consulte o site: