18/03/2020 de texto completo tecnología de recuperación

1. La búsqueda de texto completo

1.1 Clasificación de los datos

Los datos estructurados:

MySQL: tipo y tamaño de campo son fijos

Los datos no estructurados:

Buscar:

1.2 Comparación de la búsqueda y de texto completo Búsqueda general

recuperación Normal (MySQL) (adiciones y deleciones) búsqueda de texto completo (búsqueda)
Tipos de datos Los datos estructurados Los datos estructurados y datos no estructurados
proceso Crear un índice, y luego con base en la consulta ID Crear un índice invertido , a continuación, de acuerdo con el índice invertido consulta
velocidad de las consultas A veces rápido, a veces lento Ciertos rápida
Los resultados varían ordinario ancho
negocios apoyo No es compatible con las transacciones

1.3. Escenario de búsqueda de texto completo

El interior (1) Buscar

Por ejemplo: micro contratación Primus United, contrató recta

(2) la búsqueda vertical

Por ejemplo, el vídeo Tencent se puede encontrar a vídeo Sohu

(3) del motor de búsqueda

Baidu Google

2.lucene (entender)

Lucene: subyacente a toda búsqueda de texto completo populares del marco están Lucene, para lograr un repositorio de paquetes frasco (biblioteca) de búsqueda del sitio web oficial de texto completo: https: //lucene.apache.org/

Solr: Este frasco de Lucene base de datos de la biblioteca paquete de paquete de marco

elasticsearch: Marco paquete frasco de Lucene empaquetar esta biblioteca, más fuerte, más profesional que Solr, más simple

2.1 Búsqueda de texto completo

(1) Crear un proyecto vacío:

Designada: de texto completo, búsqueda

(2) crear un nuevo módulo, Lucene

(3) la adición de la dependencia pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.shenyian.demo</groupId>
    <artifactId>lucene</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- 版本锁定-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- lucene 依赖-->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>4.10.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-analyzers-common</artifactId>
            <version>4.10.3</version>
        </dependency>
        <!-- mybatis plus 的起步依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>2.3</version>
        </dependency>
        <!-- mysql 依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- 单元测试的起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!-- ik分词器 -->
        <dependency>
            <groupId>com.janeluo</groupId>
            <artifactId>ikanalyzer</artifactId>
            <version>2012_u6</version>
        </dependency>

    </dependencies>

</project>

:( carpeta de secuencias de comandos SQL en el archivo de código)

(4) editar el archivo de configuración application.yml

spring: 
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://192.168.176.109:3306/elastic_search?useUnicode=true&characterEncoding=UTF8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
    username: root
    password: ****

(5) crear una clase de arranque, añadir anotaciones MapperScan

package com.shenyian;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.shenyian.mapper")
public class LuceneApplication {

    public static void main(String[] args) {
        SpringApplication.run(LuceneApplication.class, args);
    }
}
(6) crear la clase entidad JobInfo
package com.shenyian.domain;

import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import lombok.Data;

@Data
@TableName("job_info")
public class JobInfo {
    @TableId
    private Long id;
    //公司名称
    private String companyName;
    //职位名称
    private String jobName;
    //薪资范围,最小
    private Integer salaryMin;
    //招聘信息详情页
    private String url;
}
(7) crear mapper
package com.shenyian.mapper;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.shenyian.domain.JobInfo;

public interface JobInfoMapper extends BaseMapper<JobInfo> {
}
(8) clases de prueba unidad:

Crear una base de datos de índice, añadir documentos:

  @Test
    public void test() throws Exception {

        List<JobInfo> jobInfos = jobInfoMapper.selectList(null);

        //Directory d, IndexWriterConfig conf
        Directory directory = FSDirectory.open(new File("H:\\lucene\\index"));//指定索引库保存的地址
        //Version matchVersion, Analyzer analyzer
        Analyzer analyzer = new IKAnalyzer();//中文分词器
        //Analyzer analyzer = new StandardAnalyzer();//标准分词器 对于英文识别,不识别中文
        //Analyzer analyzer = new CJKAnalyzer();//中日韩分词器 分词的不准
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LATEST, analyzer);
        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig); //用来创建索引库的工具
        for (JobInfo jobInfo : jobInfos) {
            Document document = new Document();
            document.add(new TextField("companyName", jobInfo.getCompanyName(), Field.Store.YES));
            document.add(new TextField("jobName", jobInfo.getJobName(), Field.Store.YES));
            document.add(new DoubleField("salaryMin", jobInfo.getSalaryMin(), Field.Store.YES));
            document.add(new StringField("url", jobInfo.getUrl(), Field.Store.YES));
            indexWriter.addDocument(document);//添加document 文档
        }
        indexWriter.close();//io关闭

    }

Ver índice de base de datos mediante herramientas de Lucas:

Seleccione la carpeta en la que el código de índice:


Haga clic en OK:

Índice de Biblioteca:

(9) El sistema de consulta
    @Test
    public void search() throws Exception {
        IndexReader indexReader = DirectoryReader.open(FSDirectory.open(new File("H:\\lucene\\index")));//用来读取索引库的信息
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);//是用来检索
        TopDocs topDocs = indexSearcher.search(new TermQuery(new Term("jobName", "java")), 10);//通过term查询,最多显示10条
        int totalHits = topDocs.totalHits;
        System.out.println("匹配到的数据条数:" + totalHits);
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;//通过倒排索引查询到的id数组
        for (ScoreDoc scoreDoc : scoreDocs) {
            int doc = scoreDoc.doc;//文档的id
            Document document = indexSearcher.doc(doc);//通过id查询到文档
            System.out.println(document.get("companyName"));
            System.out.println(document.get("jobName"));
            System.out.println(document.get("salayMin"));
            System.out.println(document.get("url"));
            System.out.println("=====================================");
        }
    }

palabra palabras y parada prolongada palabra de 2.2.IK

Crear un archivo en los recursos: IKAnalyzer.cfg.xml

A continuación, crear un archivo en ext.dic recursos y stopword.dic

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">  
<properties>  
    <comment>IK Analyzer 扩展配置</comment>
    <!--用户可以在这里配置自己的扩展字典 -->
    <entry key="ext_dict">ext.dic</entry>
    <!--用户可以在这里配置自己的停止词字典-->
    <entry key="ext_stopwords">stopword.dic</entry>
    
</properties>    

(1) añadir una palabras de extensión y los perfiles de palabras vacías

(2) añadir una palabra extensión

(3) crear una biblioteca de índice de nuevo, puede borrar la base de datos antes de que el índice de

Después de la configuración (4), necesita volver a cargar el documento (para eliminar la vieja carga antes):

(5) que se pueden encontrar en el plazo ampliado, palabras vacías descubrir

2.3. PPC (código de la llave abajo)

El orden predeterminado se basa partido: Si un partido es el mismo grado, a continuación, de acuerdo con la ID

PPC mayor prioridad que el grado de coincidencia, estableciendo el campo de atributos: textField.setBoost (10000); // Tasa

     @Test
    public void test() throws Exception {

        List<JobInfo> jobInfos = jobInfoMapper.selectList(null);

        //Directory d, IndexWriterConfig conf
        Directory directory = FSDirectory.open(new File("H:\\lucene\\index"));//指定索引库保存的地址
        //Version matchVersion, Analyzer analyzer
        Analyzer analyzer = new IKAnalyzer();//中文分词器
        //Analyzer analyzer = new StandardAnalyzer();//标准分词器 对于英文识别,不识别中文
        //Analyzer analyzer = new CJKAnalyzer();//中日韩分词器 分词的不准
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LATEST, analyzer);
        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig); //用来创建索引库的工具
        indexWriter.deleteAll();//清除原先的索引库
        for (JobInfo jobInfo : jobInfos) {
            Document document = new Document();
            document.add(new TextField("companyName", jobInfo.getCompanyName(), Field.Store.YES));
            document.add(new TextField("jobName", jobInfo.getJobName(), Field.Store.YES));
            document.add(new DoubleField("salaryMin", jobInfo.getSalaryMin(), Field.Store.YES));
            document.add(new StringField("url", jobInfo.getUrl(), Field.Store.YES));
            indexWriter.addDocument(document);//添加document 文档
        }
        //单独添加一个给钱的公司
        Document document = new Document();
        TextField textField = new TextField("companyName", "给钱的随便写的给了排名第一的有限公司", Field.Store.YES);
        textField.setBoost(10000); //打分
        document.add(textField);
        document.add(new TextField("jobName", "java", Field.Store.YES));
        document.add(new DoubleField("salaryMin", 30000, Field.Store.YES));
        document.add(new StringField("url", "www.suibian.com", Field.Store.YES));
        indexWriter.addDocument(document);
        indexWriter.close();//io关闭

    }

ES tiene dos puertos: 9200 (se puede acceder a través de un protocolo de navegador http) 9300 (ES racimo visitan unos a otros, el acceso protocolo TCP)

Instalación: Node.js "6.2.4 versión es la versión 6.2.4" herramienta de visualización Kibana "Google plug-ES

1, el nodo de la instalación:

(1) todo el camino hasta la próxima instalación, inteligente

(2) el control de la ventana de entrada de comando cmd: si la versión correcta instalación

2, los de instalación y es Kibana:

(1) ES y Kibana comprimen, descompresión

(2) encontraron en las soluciones de software de directorio de configuración es después de la compresión, y luego modificado como sigue:

1) elasticsearch.yml: Guardar la retención de datos de registro y dirección de

2) jvm.options: memoria de configuración de inicio ocupada

(3) añadir la carpeta de plugins en Es ik palabra plug-in, si ya tiene, a continuación, dirigir el cuarto paso:

(4) de inicio es:

(5) lanzó dos puerto 9200 se puede acceder a través de un navegador, 9300 para el clúster.

(6) Verificación: Si el navegador muestra la siguiente información ha sido instalado con éxito en es nombre los

(6) Si el inicio de ca de error, ver el mensaje de error:

(7) que se encuentra en el directorio bin de la Kibana software de instalación, puesta en Kibana:

(8) Si la consola se imprime de la siguiente manera:

(9) Kibana página abierta en un navegador, haga clic en Herramientas de desarrollo: http: // localhost: 5601

(9) del navegador Google plug-in instalado:

1) Google Plug Dirección: google --- "Más herramientas ----" extensión

2)

Descomprimir el archivo;

3) Si no hay ninguna extensión de esta carga comprimido, a continuación, haga clic en el modo de programador

4) Agregar la extensión

5) Comprobar navegador Google

6) Después de hacer clic:

3.1. Verificar si la entrada en vigor palabra ik

GET /_analyze
{
  "text": "我是一个好学生",
  "analyzer": "ik_smart"
}
或者
GET /_analyze
{
  "text": "我是一个好学生",
  "analyzer": "ik_max_word" 推荐的
}    

Kibana apoyar Estilo reparador:

PONER generalmente crear una base de datos de índice, tipo

POSTAL general, añadir y modificar documentos

Los datos obtenidos en nombre del GET

Eliminar para eliminar al general

3.2. Operación índice de la biblioteca

Crear un índice Biblioteca: PUT / shenyian

Consulta al índice Biblioteca: GET / shenyian

Retire el índice Biblioteca: Borrar / shenyian


3.3. Creación de una biblioteca de tipo de índice (tipo) (no se recomienda)

PUT /shenyian
PUT /shenyian/_mapping/goods  //创建索引库中的类型
{
  "properties": { //固定写法
     "goodsName":{// 类型中的字段
       "type": "text", //字段的field类型
       "index": true, //是否会检索
       "store": true, //是否在文档中保存
       "analyzer": "ik_max_word" //用哪个分词器
     }
  }
}

3.4. Al mismo tiempo, la biblioteca y crear un tipo de índice (tipo) (recomendado)

PUT /shenyian
{
  "mappings": {
    "goods":{
      "properties": {
         "goodsName":{
          "type": "text",
          "index": true,
          "store": true,
          "analyzer": "ik_max_word"
        },
        "price":{
          "type": "double", //double的field类型
          "index": true,
          "store": true
        },
        "image":{
          "type": "keyword", //和lucene的stringField一样,保存字符串,但是不分词
          "index": true,
          "store": true
        }
      }
    }
  }
}

Crear una plantilla (entender)

PUT /shenyian2
{
  "mappings": {
    "goods":{           
      "properties": {
        "goodsName":{ 
          "type": "text",  
          "index": true,
          "store": true,  
          "analyzer": "ik_max_word" 
        } 
    },  
    "dynamic_templates":[
        {
          "myStringTemplate":{ //自定义的模板名称
            "match_mapping_type": "string", //匹配到的字段类型
            "mapping":{
               "type": "text",//如果匹配的是字符串,那么自动textfiled类型
               "analyzer": "ik_max_word" //默认的ik_max_word分词器
            }
          }
        }
    ]
  }
 } 
}

3.5. Operación del documento

Adición de documentos:

POST /shenyian/goods  
{
  "goodsName": "小米9手机",
  "price": 2999,
  "image": "www.xiaomi9.com/9.jpg"
}
或
POST /shenyian/goods/1 如果自己给id,那么es会用我们给的id
{
  "goodsName": "小米9手机",
  "price": 2999,
  "image": "www.xiaomi9.com/9.jpg"
}

Modificar el documento por ID:

POST /shenyian/goods/7uHXmXAB2jTsz9zVCTTF //通过自动生成的id进行修改
{
  "goodsName": "小米9pro手机",
  "price": 3999,
  "image": "www.xiaomi9.com/9.jpg"
}

Por consulta id:

GET /shenyian/goods/7uHXmXAB2jTsz9zVCTTF

Mediante la supresión de Identificación:

DELETE /shenyian/goods/7uHXmXAB2jTsz9zVCTTF

3.7. Varias consultas (enfoque)

Preparación de los datos:

PUT /shenyian
{
  "mappings": {
    "goods":{
      "properties": {
        "goodsName":{
          "type": "text",
          "index": true,
          "store": true,
          "analyzer": "ik_max_word"
        },
        "price":{
          "type": "double",
          "index": true,
          "store": true
        },
        "image":{
          "type": "keyword",
          "store": true
        }
      }
    }
  }
}
POST /shenyian/goods/1 
{
  "goodsName": "小米9 手机",
  "price": 2999,
  "image":"www.xiaomi.9.jpg"
}
POST /shenyian/goods/2
{
  "goodsName": "华为 p30 手机",
  "price": 2999,
  "image":"www.huawei.p30.jpg"
}
POST /shenyian/goods/3
{
  "goodsName": "华为 p30 plus",
  "price": 3999,
  "image":"www.huawei.p30plus.jpg"
}
POST /shenyian/goods/4
{
  "goodsName": "苹果 iphone 11 手机",
  "price": 5999,
  "image":"www.iphone.11.jpg"
}
POST /shenyian/goods/5
{
  "goodsName": "苹果 iphone xs",
  "price": 6999,
  "image":"www.iphone.xs.jpg"
}
POST /shenyian/goods/6
{
  "goodsName": "一加7 手机",
  "price": 3999,
  "image":"www.yijia.7.jpg"
}
(1) Buscar
POST /shenyian/goods/_search 如果不通过id来查询,那么需要添加_search固定语法
{
  "query": { 也是固定语法
    "match_all": {}
  }
}
(2) consulta plazo

(De acuerdo con el término índice invertido a consulta)

POST /shenyian/goods/_search
{
  "query": {
    "term": {
      "goodsName": "手机"
    }
  }
}
(3) coinciden con la consulta

(Palabra de consulta de datos, y cada término de consulta de textos, dará lugar a la colección)

POST /shenyian/goods/_search
{
  "query": {
    "match": {
      "goodsName": "手机 小米"
    }
  }
}
(4) el alcance de la investigación

De acuerdo con un rango de intervalo de campo

POST /shenyian/goods/_search
{
  "query": {
    "range": {
      "price": { //通过price这个字段
        "gte": 2000,  gte:greate than equals
        "lte": 4000   lte:less than equals
      }
    }
  }
}
(5) consulta difusa

(Consulta con tolerancia a fallos, que puede permitir que la palabra equivocada, un máximo de dos)

POST /shenyian/goods/_search
{
  "query": {
    "fuzzy": { 容错查询关键字
      "goodsName": {
        "value": "iphoww",
        "fuzziness": 2 容错率,最多是2
      }
    }
  }
}
(6) Boolean consulta

(Combinación de consulta, las combinaciones de consulta se ha mencionado anteriormente)

POST /shenyian/goods/_search
{
  "query": {
    
    "bool": {
      "must": [    //下面的match查询的结构和range查询的结果的交集
        {
          "match": {      
            "goodsName": "手机 小米"
          }
        },
        
        {
          "range": {
            "price": {
              "gte": 2000,
              "lte": 4000
            }
          }
        }
      ]
    }
  }
}
POST /shenyian/goods/_search
{
  "query": {
    
    "bool": {
      "should": [ //下面的match查询的结构和range查询的结果的并集
        {
          "match": {
            "goodsName": "手机 小米"
          }
        },
        
        {
          "range": {
            "price": {
              "gte": 2000,
              "lte": 4000
            }
          }
        }
      ]
    }
  }
}
POST /shenyian/goods/_search
{
  "query": {
    
    "bool": {     must中查询出来的结果然后排除must_not中的结果
      "must": [   
        {
          "match": {
            "goodsName": "手机 小米"
          }
        },
        
        {
          "range": {
            "price": {
              "gte": 2000,
              "lte": 4000
            }
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "goodsName": "华为"
          }
        }
      ]
    }
  }
}

Las palabras clave son:

La intersección de partido && gama combinada plazo, partido, gama, borroso y así sucesivamente resultados de la consulta: mosto

De acuerdo con los resultados de los resultados de consulta obligada, o debería, y luego la eliminación de consulta must_not: must_not

gama una combinación de plazo, partido, rango, etc. consulta conjunto de resultados y partido ||: debe

En general: junto con el mosto y must_not, o junto con el debe y must_not

filtro (este filtro es un término filtro, la misma función y así se considera igual ...... MUST MUST)

3.8. Filtrar

Se filtra el campo de la pantalla, usted no desea mostrar los campos se pueden filtrar ....

incluye:

POST /shenyian/goods/_search
{
  "query": {
    "match": {
      "goodsName": "华为"
    }
  },
  "_source": {
    "includes": ["goodsName","price"]
  }
}

excluye:

POST /shenyian/goods/_search
{
  "query": {
    "match": {
      "goodsName": "华为"
    }
  },
  "_source": {
    "excludes": ["image"] 不想显示的字段
  }
}

3.8. Clasificación, paginación

POST /shenyian/goods/_search
{
  "query": {
    "match": {
      "goodsName": "手机"
    }
  },
  "sort": [   排序
    {
      "price": {
        "order": "desc"
      }
    }
  ],
  "from": 0,  分页
  "size": 2
}

3.9. Resalte (ser palabra clave buscada decoloración)

POST /shenyian/goods/_search
{
  "query": {
    "match": {
      "goodsName": "手机"
    }
  },
  "highlight": {
    "fields": {
      "goodsName": {}  //需要高亮的字段和上面的查询字段要一致
    },
    "pre_tags": "<font color=red>",  //前置html标签
    "post_tags": "</font>"          //闭合html标签
  }
}

3.10. Polimerización (paquete)

campo campo polimerizado debe ser del tipo: palabra clave

elasticsearch MySQL
Polimerización (paquete) Pail (cubo) agrupar por
avg, max, min, COUNT (*) se calcula después de un paquete medida función de agregado

polimerización mysql:

Preparar los datos:

PUT /car
{
  "mappings": {
    "orders": {
      "properties": {
        "color": {
          "type": "keyword"
        },
        "make": {
          "type": "keyword"
        }
      }
    }
  }
}
POST /car/orders/_bulk
{ "index": {}}
{ "price" : 10000, "color" : "红", "make" : "本田", "sold" : "2014-10-28" }
{ "index": {}}
{ "price" : 20000, "color" : "红", "make" : "本田", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 30000, "color" : "绿", "make" : "福特", "sold" : "2014-05-18" }
{ "index": {}}
{ "price" : 15000, "color" : "蓝", "make" : "丰田", "sold" : "2014-07-02" }
{ "index": {}}
{ "price" : 12000, "color" : "绿", "make" : "丰田", "sold" : "2014-08-19" }
{ "index": {}}
{ "price" : 20000, "color" : "红", "make" : "本田", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 80000, "color" : "红", "make" : "宝马", "sold" : "2014-01-01" }
{ "index": {}}
{ "price" : 25000, "color" : "蓝", "make" : "福特", "sold" : "2014-02-12" }
GET /car/orders/_search
{
  "from": 0,
  "size": 0, //为了不显示查询结果,不影响聚合
  "aggs": {
    "my_aggs_color": {//聚合起名
      "terms": {//固定写法
        "field": "color", //用什么字段来进行分组
        "size": 10 //最多显示多少组
      },
      "aggs": { 
        "my_avg": {//给聚合函数起个名字
          "avg": {  //根据什么聚合函数来计算:avg  max  min
            "field": "price" //什么字段来进行计算
          }
        }
      }
    }
  }
}


(Este artículo causó Xiewang Hao, particular, admiro el gran Dios, el hermano ho).

Supongo que te gusta

Origin www.cnblogs.com/ShenYian/p/12519814.html
Recomendado
Clasificación