Uso preliminar, comprensión y código de Lucene

Búsqueda de texto completo de Lucene

1. ¿Qué es la búsqueda de texto completo?

Los datos con los que entramos en contacto en la vida diaria se pueden dividir a grandes rasgos en:
  datos estructurados: se refiere a datos con una longitud y formato fijos. Tales como: datos de bases de datos, metadatos y otros
  datos no estructurados: no hay datos de formato de longitud fija. Tales como: documento de Word, archivo txt, etc.
  Podemos consultar datos estructurados a través de sentencias SQL, etc., que pueden consultar fácilmente los datos que necesitamos, pero para los datos no estructurados, será muy problemático cuando queremos obtener el vocabulario o los datos que queremos de ellos. No hay ninguna regla. encontrar.
  Para encontrar datos a partir de datos no estructurados, podemos:
  extraer datos no estructurados en un formato determinado, reorganizarlos y formar datos estructurados , de modo que podamos encontrarlos fácilmente como datos estructurados Los datos que queremos, esta parte de la información extraída de datos no estructurados y luego reorganizado, lo llamamos índice.
  Por ejemplo: en un diccionario, la explicación de cada palabra son datos no estructurados, que serán muy difíciles de encontrar. Primero podemos extraer la pronunciación o los radicales de cada palabra para formar un índice, cada uno correspondiente a un número de página, de modo que Al buscar, primero puede encontrar el número de página correspondiente a través de radicales o pronunciación, por lo que es muy conveniente encontrar palabras.

  Este proceso de crear un índice primero y luego buscar en el índice se denomina Búsqueda de texto completo.

Proceso de búsqueda de texto completo:
Inserte la descripción de la imagen aquí
1. Verde indica el proceso de indexación, indexando el contenido original que se buscará para construir una biblioteca de índices, el proceso de indexación incluye:
determinar el contenido original que es el contenido que se buscará, recopilar documentos, crear análisis de documentos , documentos de indexación de documentos

2. El rojo indica el proceso de búsqueda, la búsqueda de contenido de la biblioteca de índices, el proceso de búsqueda incluye: el
usuario crea una consulta a través de la interfaz de búsqueda para realizar la búsqueda, y los resultados de la búsqueda se representan desde la biblioteca de índices

2. Algunos conceptos en lucene

Archivo original:
  es decir, queremos encontrar en esos datos, y estos datos son los datos originales.
  Tales como: los datos en la base de datos, el archivo txt en el disco ...


Objeto de documento: después de
  obtener el contenido en el archivo original, necesitamos crear un índice, agregar el contenido al objeto de documento y luego almacenarlo en la biblioteca de índices y el objeto de documento Contiene muchos objetos de campo. El objeto de documento puede verse como una tabla en la base de datos y el campo puede verse como un atributo en la base de datos.
Inserte la descripción de la imagen aquí
Nota: Cada documento puede tener múltiples campos, diferentes documentos pueden tener diferentes campos y el mismo documento puede tener el mismo campo (el nombre de dominio y el valor del campo son los mismos)

Cada documento tiene un número único, que es la identificación del documento.


3. Autocomprensión de Lucene

Lucene realmente lee los datos originales y luego encapsula cada dato original como un objeto de documento separado. Al agregar una biblioteca de índice directo, automáticamente segmentará cada campo de acuerdo con el tokenizador para formar un diccionario, y luego el diccionario realiza el procesamiento del índice y luego, el índice (diccionario) y los objetos de documento se agregan a la biblioteca de índices, así como la relación entre ellos (estructura de índice invertida). Cuando un usuario busca un vocabulario, primero busca en el índice (diccionario), luego encuentra el objeto de documento correspondiente de acuerdo con la relación entre el diccionario y el objeto de documento, y luego busca el objeto de campo correspondiente para averiguar el contenido.


Estructura de índice invertida:
Inserte la descripción de la imagen aquí
a la izquierda está la lista de diccionarios, a la derecha está la tabla invertida, es decir, la identificación del documento de cada palabra en esos documentos. Es decir, la palabra de consulta, buscar el documento correspondiente y encontrar el contenido, que es la estructura de índice invertida.

4. Pasos para usar lucene

1. Importe el paquete del tarro.
Inserte la descripción de la imagen aquí

2. Cree el archivo original
Inserte la descripción de la imagen aquí
3. Cree la biblioteca de índices, analice y registre todos los archivos anteriores en la biblioteca de índices

@Test
    public void createLucene() throws IOException {
    
    
        //1.创建directory对象,指定索引库的存放位置
        //此方式为在本地磁盘存储索引库
        Directory dir = FSDirectory.open(new File("D:\\luncene").toPath());
        //此方式为索引库存放于内存中(不建议:每次加载太慢)
        //Directory dir1 = new RAMDirectory();
        //2.配置设置:默认使用的是StandardAnalyzer解析器,对中文不友好,后期可以在构造参数中指定中文解析器
        IndexWriterConfig config = new IndexWriterConfig();
        //3.根据directory和indexWriterConfig创建IndexWriter对象,用于向索引库中写数据
        IndexWriter writer = new IndexWriter(dir,config);
        //4.加载数据,并封装为document对象
        File filePaths = new File("D:\\lucenePro");
        //获取文件夹下所有的file
        File[] files = filePaths.listFiles();
        //遍历files数组,获取每一个file
        for (File file : files) {
    
    
            //获得文件名
            String fileName = file.getName();
            //获取文件的路径
            String filePath = file.getPath();
            //获取文件的内容
            String fileContent = FileUtils.readFileToString(file);
            //获取文件的大小
            long fileSize = FileUtils.sizeOf(file);

            //创建域(属性)对象,并在域对象中存放对应的值
            Field fieldName = new TextField("name",fileName, Field.Store.YES);
            Field fieldPath = new TextField("path",filePath, Field.Store.YES);
            Field fieldContent = new TextField("content",fileContent, Field.Store.YES);
            Field fieldSize = new TextField("size",fileSize+"", Field.Store.YES);
            //创建document对象,并把域对象赋值
            Document document = new Document();
            document.add(fieldName);
            document.add(fieldPath);
            document.add(fieldContent);
            document.add(fieldSize);

            //写入到索引库
            writer.addDocument(document);

        }

        //释放写资源
        writer.close();

    }

Nota: Si usa FileUtis, necesita importar el paquete commons.io.jar

Después de la ejecución, busque la ubicación de la carpeta donde se creó el objeto de directorio y podrá ver:
Inserte la descripción de la imagen aquí
la carga se realizó correctamente.

5. Use luke para ver la biblioteca de índices

dirección de descarga de luke:
dirección de descarga de luke

Después de la descarga, debe ingresar al directorio, abrir la ventana negra en el directorio donde se encuentra el archivo pom.xml y ejecutar el comando: comando del paquete mvn para usar luke, de lo contrario
ERROR, inhabilitado para acceder al archivo jar:. \ Target \ luke -Swings-with- deps.jar error

Además: descargue el último lucene, traerá luke, solo haga doble clic para usarlo.

6. Consultar la biblioteca de índices

@Test
    public void queryLucene() throws IOException {
    
    
        //创建Directory对象,指向索引库
        Directory dir = FSDirectory.open(new File("D:\\luncene").toPath());
        //创建reader对象
        IndexReader reader = DirectoryReader.open(dir);
        //创建sercher查找对象
        IndexSearcher searcher = new IndexSearcher(reader);
        //封装查询条件对象 term:第一个参数:你要查询那个域的,第二个参数:你要查询的参数
        Query query = new TermQuery(new Term("name","apache"));
        //查询 第一个参数:你封装的查询条件,第二个参数:最多查询多少条的数据
        TopDocs topDocs = searcher.search(query, 10);
        //获取查询的总条数
        TotalHits totalHits = topDocs.totalHits;
        System.out.println(totalHits);

        //根据获取的topDocs对象,获得ScoreDoc[],ScoreDoc里面存放的是document的id
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {
    
    
            //根据document的id查询document对象
            Document doc = searcher.doc(scoreDoc.doc);
            //获取内容
            String name = doc.get("name");
            String path = doc.get("path");
            String content = doc.get("content");
            String size = doc.get("size");
            System.out.println(name);
            System.out.println(path);
            System.out.println(content);
            System.out.println(size);
            System.out.println("-----------------------------------");
        }
        reader.close();

    }

7. Segmentador de palabras chinas

Usando el tokenizador estándar incorporado, puede segmentar muy bien las palabras en inglés, pero el chino no es muy amigable y clasificará cada carácter como una palabra. Si desea segmentar palabras chinas, debe usar el segmentador de palabras chinas: IKAnalyzer Cómo
  usar:
1. Importe el paquete jar, importe la configuración
Inserte la descripción de la imagen aquí
Configuración:
hotword.dic: indica algunas palabras especiales, después de agregarlas, puede ser segmentado por el analizador
stopword.dic: lista de palabras de parada y palabras sensibles
IkAnalyzer.cfg.xml: información de configuración de IkAnalyzer

Casos de uso:

 /**
     * 使用中文分析器分词
     */
    @Test
    public void createIndexByIk() throws IOException {
    
    
        //创建directory对象
        Directory dir = FSDirectory.open(new File("D:\\luncene").toPath());
        //创建IndexWriterConfig对象,并指定分词器
        IndexWriterConfig writerConfig = new IndexWriterConfig(new IKAnalyzer());
        //创建IndexWriter对象
        IndexWriter writer = new IndexWriter(dir,writerConfig);
        //获取数据
        String text = "但是老外写的分词器对中文分词一般都是单字分词,分词的效果不好。 国人林良益写的IK Analyzer应该是最好的Lucene中文分词器之一,而且随着Lucene的版本更新而不断更新";
        Field field = new TextField("name",text, Field.Store.YES);
        Document document = new Document();
        document.add(field);

        writer.addDocument(document);
        writer.close();
    }

Efecto:
Inserte la descripción de la imagen aquí
si necesita realizar una segmentación especial en algunas palabras, como los nombres de empresas, debe mantenerlas por separado en la palabra activa.

8. La biblioteca de índices debe mantenerse y agregarse

Igual que la biblioteca de índices inicial, excepto que se trata de un solo archivo.

9. Índice de eliminación de la biblioteca de índices

1. Eliminar todos los índices

 @Test
    public void deleteAllIndex() throws IOException {
    
    
        IndexWriter writer = new IndexWriter(FSDirectory.open(new File("D:\\luncene").toPath()),new IndexWriterConfig(new IKAnalyzer()));
        //删除所有的索引,此方法慎用,一旦删除,无法恢复!!!
        writer.deleteAll();
        writer.close();
    }

2. Elimina el índice según Consulta

@Test
    public void deleteByQuery() throws IOException {
    
    
        IndexWriter writer = new IndexWriter(FSDirectory.open(new File("D:\\luncene").toPath()),new IndexWriterConfig(new IKAnalyzer()));
        //声明Query
        Query query = new TermQuery(new Term("name","web"));
        //根据query条件删除document
        writer.deleteDocuments(query);
        writer.close();
    }

10. Actualice la biblioteca de índices

La actualización aquí es en realidad para eliminar el índice primero y agregar el índice.

11. Ver el índice

1.Query:
TermQuery: consulta de palabra clave

  Sin demostración, ibid.


RangeQuery: consulta de rango

@Test
    public void selectQuery() throws IOException {
    
    
        //Query有两个子类:
        //1.TermQuery:关键词查询,需要提供查询的域和要查询的关键词,不演示
        //2.RangeQuery:范围查询,一般用于整数
        IndexReader indexReader = DirectoryReader.open(FSDirectory.open(new File("D:\\luncene").toPath()));
        //获取查询对象
        IndexSearcher searcher = new IndexSearcher(indexReader);
        //获取查询条件LongPoint:这个要看你存储的时候,使用的是什么类型的,如果是int,就替换为intPoint
        Query query = LongPoint.newRangeQuery("size",10l,100l);
        TopDocs topDocs = searcher.search(query, 10);
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {
    
    
            System.out.println(searcher.doc(scoreDoc.doc).get("name"));
        }
        indexReader.close();

    }

2.queryparser: primero segmente las condiciones de la consulta
y luego importe un paquete jar después de consultar de acuerdo con la estructura de segmentación :
Inserte la descripción de la imagen aquí
prueba:

 @Test
    public void QueryParserTest() throws IOException, ParseException {
    
    
        IndexReader indexReader = DirectoryReader.open(FSDirectory.open(new File("D:\\luncene").toPath()));
        IndexSearcher searcher = new IndexSearcher(indexReader);
        //创建QueryParser对象  参数1:默认的搜索域,当没有提供搜索域的时候,去这个域搜索,参数2:使用的分析器
        QueryParser queryParser = new QueryParser("name",new IKAnalyzer());
        //设置查询条件
        Query query = queryParser.parse("Lucene是java开发的");
        //查询
        TopDocs topDocs = searcher.search(query, 10);
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {
    
    
            Document doc = searcher.doc(scoreDoc.doc);
            System.out.println(doc.get("name"));
        }
        indexReader.close();
    }

El resultado de la búsqueda es:
primero segmenta las condiciones de tu consulta y luego consulta de acuerdo a cada palabra después de la segmentación, siempre que la consulta encuentre una relevante, será consultada.









El uso inicial de Lucene ha terminado y la mayoría de los proyectos utilizan posteriormente frameworks desarrollados en base a Lucene: es, solr, etc.

Supongo que te gusta

Origin blog.csdn.net/weixin_43431123/article/details/112480828
Recomendado
Clasificación