English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
0 Introducción
Con el desarrollo de la World Wide Web y la llegada de la era de los grandes datos, se producen, almacenan, transmiten y transforman ingentes cantidades de información digital cada día. ¿Cómo encontrar de manera específica la información que satisfaga nuestras necesidades en medio de la gran cantidad de información, y organizarla y utilizarla de manera ordenada se ha convertido en un gran desafío. La tecnología de búsqueda completa es una de las aplicaciones más comunes de búsqueda de información en la actualidad. El uso de motores de búsqueda en la vida diaria, la búsqueda de información en blogs y foros, los principios básicos de estas búsquedas son la tecnología de búsqueda completa que se va a implementar en este artículo. Con la realización de la digitalización de la información documental, almacenar información de manera efectiva y extraerla de manera precisa y oportuna es una base que cada empresa, organización y unidad debe manejar bien. Hay muchos teoremas y métodos maduros de búsqueda completa en inglés, y el motor de búsqueda completo de código abierto Lucene es un subproyecto del proyecto Jakarta del Grupo de Proyectos Apache. Su objetivo es proporcionar a los desarrolladores de software una herramienta de paquete simple y fácil de usar, lo que facilita la implementación de la función de búsqueda completa en el sistema objetivo. Lucene no admite chino, pero ya hay muchos tokenizadores de código abierto en chino que pueden indexar contenido chino. Este artículo, basado en el estudio de los principios centrales de Lucene, ha implementado respectivamente la captura y búsqueda de páginas web en chino e inglés.
1 Introducción a Lucene
1.1 Introducción a lucene
Lucene es un paquete de herramientas de motor de búsqueda de texto completo escrito en Java, que realiza la construcción de índices y la función de búsqueda de dos funciones principales, y ambas son independientes, lo que permite a los desarrolladores expandirse fácilmente. Lucene proporciona una rica API, que permite una interacción conveniente con la información almacenada en el índice. Es necesario aclarar que no es una aplicación de búsqueda de texto completo completa, sino que proporciona funciones de indexación y búsqueda para aplicaciones. Es decir, para que Lucene funcione realmente,还需在其基础上做一些必要的二次开发。
El diseño estructural de Lucene es bastante similar al diseño de bases de datos, pero el índice de Lucene es muy diferente de la base de datos. Tanto la base de datos como Lucene crean índices para facilitar la búsqueda, pero la base de datos solo crea índices para campos parte y necesita convertir los datos en información formateada y guardarla. Mientras que la búsqueda de texto completo crea índices de toda la información de una manera determinada. Las diferencias y similitudes entre las dos búsquedas se muestran en la tabla1-1Como se muestra.
Tabla1-1:Comparación entre la búsqueda de bases de datos y la búsqueda de Lucene
Comparación |
Búsqueda de Lucene |
Búsqueda de bases de datos |
Búsqueda de datos |
Recuperar de los archivos de índice de Lucene |
Recuperar registros a través de la búsqueda de índices de la base de datos |
Estructura de índice |
Documento (Document) |
Registro (Record) |
Resultados de la consulta |
Hit: documentos que satisfacen la relación |
Conjunto de resultados de la consulta: los registros que contienen palabras clave |
Búsqueda de texto completo |
Admite |
No admite |
Consulta borrosa |
Admite |
No admite |
Ordenamiento de resultados |
Configurar el peso, realizar el ordenamiento de relevancia |
No se puede ordenar |
1.2 Estructura general de lucene
La forma de publicación del paquete de software Lucene es un archivo JAR, la actualización de la versión es rápida y la diferencia entre las versiones es grande, en este artículo se utiliza5.3.1Versión del paquete, los subpaquetes principales utilizados se muestran en la tabla1-2Como se muestra.
Tabla1-2:Subpaquete y función
Nombre del paquete |
Función |
Org .apache.lucene .analysis |
Análisis |
Org .apache.lucene .document |
Gestión de documentos de índice |
Org .apache.lucene .index |
Operaciones de índice, incluyendo agregar, eliminar, etc. |
Org .apache.lucene .queryParser |
Constructor de expresiones de búsqueda, consulta |
Org .apache.lucene .search |
Gestión de búsqueda |
Org .apache.lucene .store |
Gestión de almacenamiento de datos |
Org .apache.lucene .util |
Clase pública |
1.3 Diseño de arquitectura de lucene
Las funciones de Lucene son muy potentes, pero en esencia, incluyen dos partes: una es la introducción de términos cortados del contenido del texto en la base de datos de índice; la otra es la devolución de resultados según las condiciones de búsqueda, es decir, la creación de índice y la búsqueda.
Como se muestra1-1Como se muestra, este artículo lanza la interfaz externa y la fuente de información, y se centra en la indexación y búsqueda del contenido del texto de la caza de páginas web.
Gráfico1-1:Diseño de arquitectura de Lucene
2 Instalación de JDK y configuración de variables de entorno
1.Descarga de JDK:
Descargue el paquete comprimido que coincide con la versión del sistema en el sitio web de oracle. Haga clic en instalar, siga las instrucciones para instalar, durante el proceso de instalación se le preguntará si desea instalar jre, haga clic en sí.
http://www.oracle.com/technetwork/java/javase/descargas/index.html
2.Configuración de las variables de entorno:
(1)Botón derecho del ratón en Computadora => Propiedades => Configuración del sistema avanzado => Variables de entorno => Variables del sistema => Nuevo => JAVA_HOME: ruta de instalación
(2)Agregar nuevo en Path => %JAVA_HOME%\bin
3.Prueba de si es exitoso:
Comienzo=》Ejecutar=》CMD presione Enter en la ventana DOS emergente
Entrada: java -version mostrará información de versión,
Entrada: javac aparece información de uso de javac
Aparece como se muestra2-1Se muestra como exitoso.
Gráfico2-1:Prueba de configuración de java con el cuadro de comandos cmd
3 Escribir código en Java para obtener el contenido de la página web
Debido a que Lucene requiere usar diferentes analizadores de palabras para diferentes idiomas, en inglés se utiliza el analizador de palabras estándar, y en chino se elige usar el analizador de palabras smartcn. Al obtener páginas web, primero se obtiene la página web y se guarda como archivo html, en html debido a la interferencia de las etiquetas, afectará el efecto de la búsqueda, por lo tanto, se debe eliminar las etiquetas html y convertir el contenido del texto en archivo txt para guardar. Además del analizador de palabras, el chino e inglés son básicamente idénticos, por lo que el código y los resultados de los experimentos posteriores elegirán uno. Este artículo selecciona cincuenta páginas web de historias chinas y historias inglesas como ejemplo.
El diseño específico del código se muestra en la siguiente figura: Url2Html.java convierte la página web de la URL de entrada en archivo html, Html2El archivo Txt.java realiza la eliminación de etiquetas de documento html, guardándolo como documento txt. El código específico se muestra en la figura3-1y3-2.
public void way(String filePath,String url) throws Exception{ File dest = new File(filePath);//Crear archivo InputStream is;//Recibir flujo de entrada de bytes FileOutputStream fos = new FileOutputStream(dest);//Flujo de salida de bytes URL wangzhi = new URL(url);//Establecer la URL del sitio web is = wangzhi.openStream(); BufferedInputStream bis = new BufferedInputStream(is);//Añadir buffer al flujo de entrada de bytes BufferedOutputStream bos = new BufferedOutputStream(fos);//Añadir buffer al flujo de salida de bytes /* * Leer bytes */ int length; byte[] bytes = new byte[1024*20]; while((length = bis.read(bytes, 0, bytes.length)) != -1{ fos.write(bytes, 0, length); } /* * Cerrar flujos de entrada/salida y de buffer */ bos.close(); fos.close(); bis.close(); is.close(); }
public String getBody(String val){ String zyf = val.replaceAll("<",/?[^>]+>", ""); //Elimina las etiquetas <html> return zyf; } public void writeTxt(String Str,String writePath) { File writename = new File(writePath); try { writename.createNewFile(); BufferedWriter out = new BufferedWriter(new FileWriter(writename)); out.write(Str); out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } }
Tomemos como ejemplo la página web de la historia de hadas "El lobo tonto va a la escuela", configurando la ruta del documento como "E:\work \lucene \test \data \html" y "E:\work\lucene\test\data\txt", y en cada lectura de la página web, se deben establecer dos parámetros: el nombre del archivo filename y la obtención de la dirección web url. Crear una función main nueva para llamar a estos dos métodos. La implementación específica se muestra en la figura3-3Como se muestra:
public static void main(String[] args) { String filename = "jingdizhi";//nombre del archivo String url = "http://www.51test.net/mostrar/8072125.html";//url de la página web a extraer String filePath = "E:\\work\\lucene\\test\\data\\html\\"+filename+.html;//escribir la ruta del archivo html+nombre de archivo String writePath = "E:\\work\\lucene\\test\\data\\txt\\"+filename+.txt;//escribir la ruta del archivo txt+nombre de archivo Url2Html url2html = new Url2Html(); try { url2html.way(filePath,url); } catch (Exception e) { e.printStackTrace(); } Html2Txt html2txt = new Html2Txt(); String read=html2txt.readfile(filePath);//leer archivo html String txt = html2txt.getBody(read);//eliminar etiquetas html System.out.println(txt); try { html2txt.writeTxt(txt,writePath); } catch (Exception e) { e.printStackTrace(); } }
Después de ejecutar el programa, se crean 'estudiante_blanco_va_a_la_escuela.html' y 'estudiante_blanco_va_a_la_escuela.txt' en dos carpetas diferentes.
4 Crear índices
Los principios básicos de índice y búsqueda son los siguientes:
Crear índices: Los índices del motor de búsqueda es en realidad la implementación de 'palabra-La estructura de datos específica de 'matriz de documentos'. También es el primer paso para realizar búsqueda de texto completo, Lucene proporciona la clase IndexWriter para la gestión de índices, que incluye principalmente add(), delete(), update(). Además, la configuración de valores de权的, a través de la configuración de diferentes valores de índice, se puede retornar según el tamaño de la relevancia en la búsqueda.
Realizar búsqueda: la búsqueda directa original es una búsqueda secuencial de documentos, después de crear el índice, se puede encontrar la posición de aparición de las palabras en los documentos a través de la búsqueda de índices, y luego devolver la posición y la palabra del ítem de índice correspondiente. Lucene proporciona la clase IndexSearcher para la búsqueda de documentos, la forma de búsqueda principal se divide en dos tipos, primero: Term, para la búsqueda de términos individuales; segundo: Parser, puede construir expresiones de búsqueda personalizadas, hay muchos tipos de búsqueda, los métodos específicos se implementarán en las demostraciones posteriores.
4.1 Entorno de experimentación
Este PC utiliza windows 10x64Sistema operativo,8GB de memoria,256Solid State Drive (SSD). El entorno de desarrollo es Myeclipse 10, versión de JDK1.8. Durante el proceso del experimento, debido a la transformación de parte de la gramática, varios Class adoptan1.6Implementación de versión.
4.2 Crear índices
Crear un repositorio de índices es agregar registros de índices uno por uno al repositorio de índices, Lucene proporciona una interfaz para agregar un registro de índice, agregar índices.
Principalmente se utilizan 'escritor de índices', 'documento', 'dominio' esto3 Clase. Para crear un índice, primero se debe construir un objeto Documento documento, determinar los dominios del Documento, lo que es similar a la creación de la estructura de tabla en una base de datos relacional, el Documento es equivalente a una fila de una tabla, y el dominio es equivalente a una columna de una fila, en Lucene, para satisfacer las necesidades de propiedades y datos de salida de diferentes dominios, se pueden elegir diferentes índices para los dominios./Las reglas de almacenamiento de campos, en este experimento, el nombre de archivo fileName, la ruta completa fullPath y el contenido del texto content se utilizan como dominios de Document.
IndexWriter es responsable de recibir los documentos nuevos y escribirlos en la base de índices. Al crear el 'escritor de índices' IndexWriter, es necesario especificar el analizador de lenguaje utilizado. La creación de índices se divide en dos categorías: primero: índices no ponderados; segundo: índices ponderados.
public Indexer(String indexDir) throws Exception{ Directory dir = FSDirectory.open(Paths.get(indexDir)); Analyzer analyzer = new StandardAnalyzer(); // Término de análisis estándar //SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(); IndexWriterConfig iwc = new IndexWriterConfig(analyzer); writer = new IndexWriter(dir, iwc); }
Configurar el campo de índice, Store indica si se almacena el contenido del índice: fileName y fullPath ocupan menos memoria y se pueden almacenar para facilitar la búsqueda y devolución.
private Document getDocument(File f) throws Exception { Document doc = new Document(); doc.add(new TextField("contents", new FileReader(f))); doc.add(new TextField("fileName", f.getName(), Store.YES)); doc.add(new TextField("fullPath", f.getCanonicalPath(), Store.YES));//índice de ruta return doc; }
Después de ejecutar el código principal, los resultados se muestran en la figura: al diseñar un archivo de índice, se devuelve el archivo "archivo de índice:"+ruta del archivo
4.3 La eliminación y modificación de índices
Las operaciones comunes en la base de datos incluyen CRUD (adición, eliminación, modificación, consulta), la adición es la selección y creación de ítems de índice, la consulta, como función más central, se discutirá más adelante, aquí se registra principalmente los métodos utilizados en la eliminación y actualización de índices.
La eliminación se divide en dos tipos, incluyendo la eliminación común y la eliminación completa, ya que la eliminación de índices afecta a toda la base de datos y, para sistemas grandes, la eliminación de índices significa realizar cambios en la infraestructura del sistema, lo que consume mucho tiempo y esfuerzo y no puede ser revertido. Anteriormente, cuando se veía la creación de índices, se generaban varios archivos pequeños, y cuando se realizaba una búsqueda, se combinaban estos archivos y se realizaba la búsqueda. La eliminación común solo realiza una marca simple en los índices establecidos, lo que hace que no se pueda realizar una búsqueda y devolver. La eliminación completa destruye los índices y no se puede revertir.1tomando como ejemplo el índice de:}}
Eliminación normal (antes de la fusión):
writer.deleteDocuments(new Term("id","1")); writer.commit();
Eliminación completa (después de la fusión):
writer.deleteDocuments(new Term("id","1")); writer.forceMergeDeletes(); // Borrado forzado writer.commit();
El principio de modificación del índice es bastante simple, es decir, realizar una cobertura en el índice existente, el código de implementación es similar al aumento del índice mencionado anteriormente, no se hace una explicación detallada aquí.
4.4 Weighting del índice
Lucene se ordena por relevancia por defecto, Lucene proporciona un parámetro de Boosting para Field que se puede configurar, este parámetro se utiliza para representar la importancia del registro, al satisfacer las condiciones de búsqueda, se consideran primero los registros de alta importancia, los resultados se retornan primero, si hay muchos registros, los registros de bajo valor se colocan después de la primera página, por lo que la operación de weighting del índice es un factor importante que afecta la satisfacción de los resultados de retorno, al diseñar sistemas de información en la práctica, debe haber una fórmula de cálculo de valor de weighting estricta, lo que facilita la modificación del valor de weighting de Field, satisface mejor las necesidades del usuario.
Por ejemplo, los motores de búsqueda dan un peso más alto a las páginas con alto clic y enlaces entrantes y salientes, y se colocan en la primera página al retornar. El código de implementación se ilustra en la figura4-1Como se muestra, la comparación entre los resultados sin weighting y con weighting se ilustra en la figura4-2Como se muestra.
TextField field = new TextField("fullPath", f.getCanonicalPath(), Store.YES); if("A GREAT GRIEF.txt".equals(f.getName())){ field.setBoost(2.0f);//Weighting el path fullPath del archivo secondry story.txt; } //El peso predeterminado es1.0, cambiado a1.2Es decir, aumentar el peso. doc.add(field);
Gráfico4-1Weighting de índice
Gráfico4-2Antes de weighting
Gráfico4-2Después de weighting
Por gráfico4-2Los resultados muestran que, sin weighting, se retornan en orden alfabético, por lo que first se encuentra antes de secondry. Después de que el path de secondry nombrado se weight, cambia el orden de retorno, realizando la prueba de weighting.
5 Realizar la búsqueda
La interfaz de búsqueda de Lucene se compone principalmente de QueryParser, IndexSearcher, Hits.3 Estas clases constituyen, QueryParser es el analizador de consultas, responsable de analizar las palabras clave de consulta presentadas por el usuario, al crear un nuevo analizador se necesita especificar el dominio a analizar y qué analizador de lenguaje se utiliza, el analizador de lenguaje utilizado aquí debe ser el mismo que el analizador utilizado al crear el índice, de lo contrario los resultados de la consulta no serán correctos. IndexSearcher es el buscapalabras de índice, al instanciar IndexSearcher se necesita especificar el directorio del repositorio de índice, IndexSearcher tiene un método search que ejecuta la búsqueda del índice, este método acepta Query como parámetro, y devuelve Hits, Hits es una colección de resultados de búsqueda ordenados, los elementos de la colección son Document. A través del método get de Document se pueden obtener las información de este documento correspondiente al archivo, como: nombre de archivo, ruta de archivo, contenido de archivo, etc.
5.1 Consulta básica
Como se muestra, hay dos formas principales de consulta, pero se recomienda usar la primera construcción de expresión de QueryParser, que puede tener una combinación flexible, incluyendo expresiones lógicas booleanas, coincidencia borrosa, etc., pero el segundo Term solo puede aplicarse a consultas de vocabulario.
1. Construcción de la expresión de QueryParser:
QueryParser parser=new QueryParser("fullPath", analyzer); Query query=parser.parse(q);
2. Búsqueda de elementos específicos:
Term t = new Term("fileName", q); Query query = new TermQuery(t);
Los resultados de la consulta se muestran en la imagen5-1Como se muestra: Tomemos como ejemplo la búsqueda de archivos con nombre fileName que contienen "grande".
Gráfico5-1: Resultados de la consulta "grande"
5.2 Consulta borrosa
Al construir QueryParser, se puede lograr la coincidencia exacta y la coincidencia borrosa mediante la modificación de la palabra clave q. La coincidencia borrosa se modifica agregando "~" después de "q". Como se muestra en la imagen5-2Como se muestra:
Gráfico5-2: Coincidencia borrosa
5.3 Consulta de condiciones limitadas
Las consultas de lógica booleana y las consultas borrosas solo necesitan cambiar la palabra clave de consulta q, mientras que las consultas de condiciones limitadas requieren establecer la expresión de query, y se dividen principalmente en las siguientes categorías:
Se enumeran las consultas aplicadas para la búsqueda de rangos de elementos especificados, rangos numéricos, inicio de cadena específico y búsqueda de múltiples condiciones, el parámetro true indica: si incluye el límite superior e inferior.
Rango de elementos especificados:
TermRangeQuery query=new TermRangeQuery("desc", new BytesRef("b".getBytes()), new BytesRef("c".getBytes()), true, true);
指定数字范围:
NumericRangeQuery<Integer> query=NumericRangeQuery.newIntRange("id", 1, 2, true, true);
指定字符串开头:
PrefixQuery query=new PrefixQuery(new Term("city","a"));
多条件查询:
NumericRangeQuery<Integer>query1=NumericRangeQuery.newIntRange("id", 1, 2, true, true); PrefixQuery query2=new PrefixQuery(new Term("city","a")); BooleanQuery.Builder booleanQuery=new BooleanQuery.Builder(); booleanQuery.add(query1,BooleanClause.Occur.MUST); booleanQuery.add(query2,BooleanClause.Occur.MUST);
5.4 高亮查询
在百度、谷歌等搜索引擎中,进行查询时,返回的网页包含查询关键字的时候会显示为红色,且进行摘要显示,即对包含关键字的部分内容进行截取并返回。高亮查询即为实现对关键字的样式更改,本实验在myeclipse中进行,返回结果并不会有样式的改变,只会对返回内容的关键字添加html标签,如果显示到网页即产生样式的变化。
高亮的设置代码如图5-3如图所示,结果如图5-4如图所示,会对南京匹配词添加<b>和<font>标签,显示到网页上为加粗和变红。
QueryScorer scorer=new QueryScorer(query); Fragmenter fragmenter=new SimpleSpanFragmenter(scorer); SimpleHTMLFormatter simpleHTMLFormatter=new SimpleHTMLFormatter("<b><font color='red'>","</font></b>"); Highlighter highlighter=new Highlighter(simpleHTMLFormatter, scorer); highlighter.setTextFragmenter(fragmenter);
Gráfico5-3:configuración de resaltado
Gráfico5-4:resaltado de resultados
6 Problemas y deficiencias encontradas durante el experimento
Lucene se actualiza rápidamente, entre la versión de jdk, la versión de eclipse y la versión de lucene, se necesita una buena conexión, de lo contrario, causará muchos incompatibles, en la versión de depuración y jdk1.6y jdk1.8en la elección se encuentran muchos problemas, como el método append en el método de captura de páginas web1.8versión ya ha sido eliminada, no se puede usar. Sin embargo, la lectura de la ruta de los documentos FSDirectory.open() necesita jdk1.8sólo se admite.
Las deficiencias principales de este experimento se manifiestan en:
la flexibilidad del código es baja, al escanear las páginas web, es necesario hacerlo manualmente y se necesita realizar para chino e inglés por separado, se debe perfeccionar el código para que el idioma de la página web pueda ser juzgado y luego seleccionar automáticamente diferentes tokenizadores para ejecutar.
la reutilización del código es baja, sin una clasificación razonable y la construcción de métodos, para simplificar, básicamente se realiza mediante comentarios y marcadores en varios códigos principales para lograr el efecto,有待改进.
la portabilidad del código es baja, el análisis de las páginas web utiliza jdk1.6versión, la implementación de Lucene utiliza jdk1.8versión, al exportarla a otros equipos, es necesario realizar algunas modificaciones y configuraciones del entorno, no se puede lograr una operación una vez pulsada.
7 Resumen
Desde el principio del Lucene, he entendido la idea y el método de la búsqueda de texto completo, y he realizado experimentos y pruebas de las funciones comunes. En el proceso del experimento, he entendido la原理 de los motores de búsqueda, basado en el contenido del curso de investigación de información, he tenido una mejor experiencia práctica. Lucene es un excelente marco de tecnología de búsqueda de texto completo de código abierto, mediante un estudio profundo, es más familiar con su mecanismo de implementación, en el proceso de estudio, he aprendido muchos métodos y pensamientos de programación orientada a objetos, su excelente estructura de sistema y expandibilidad son dignos de estudiar y referirse.
Declaración: El contenido de este artículo se obtiene de la red, pertenece a los derechos de autor del propietario, el contenido se contribuye y carga de manera autónoma por los usuarios de Internet, este sitio web no posee los derechos de propiedad, no se ha realizado un procesamiento editorial humano y no asume responsabilidad por las responsabilidades legales relacionadas. Si encuentra contenido sospechoso de copyright, por favor envíe un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, reemplace # con @) para denunciar y proporcionar evidencia relevante. Una vez verificada, este sitio eliminará inmediatamente el contenido sospechoso de infracción.