所有由zhufenghua发布的文章

ElasticSearch插入、更新、查询、删除一条记录

插入一条记录:

可以指定ID,如果不指定,则自动生成一个ID

POST /index_name/_doc/1
{
  "content":"红米手机",
  "title": "手机",
  "publish_time": 1653408000000
}

字段说明:index_name为库,_doc是一种格式说明要插入数据库中而不是内存中,1是ID可省略。中间的内容是自定义的mapping字段。

更新一条数据:

POST /index_name/_doc/1
{
  "content":"红米手机",
  "title": "手机",
  "publish_time": 1653408000000
}

说明:更新时,必须指定ID,其语法格式和新增是一样的,也就是数据不存在时为新增、数据存在时为更新。

通过ID查询一条数据:

GET /index_name/_doc/1

通过ID删除一条数据

DELETE /index_name/_doc/1

如果不知道ID,可以通过 match 获取,比如查询10000条数据:

GET /index_name/_search
{
    "query": {
        "match_all": {}
    },
    "size": 10000
}

ElasticSearch类型之text和keyword

text 和 keyword 都是字符串类型。

text类型的一些特点:(text是文本类型,默认会进行全文检索)

1:支持分词,全文检索,支持模糊、精确查询,不支持聚合,排序操作;
    2:test类型的最大支持的字符长度无限制,适合大字段存储;
使用场景:
    存储全文搜索数据, 例如: 邮箱内容、地址、代码块、博客文章内容等。
    默认结合standard analyzer(标准解析器)对文本进行分词、倒排索引。
    默认结合标准分析器进行词命中、词频相关度打分。

keyword的一些特点:(keyword是一个关键字,所以不分词)

1:不进行分词,直接索引,支持模糊、支持精确匹配,支持聚合、排序操作。
2:keyword类型的最大支持的长度为——32766个UTF-8类型的字符,可以通过设置ignore_above指定自持字符长度,超过给定长度后的数据将不被索引,无法通过term精确匹配检索返回结果。

使用场景:
存储邮箱号码、url、name、title,手机号码、主机名、状态码、邮政编码、标签、年龄、性别等数据。
用于筛选数据(例如: select * from x where status='open')、排序、聚合(统计)。
直接将完整的文本保存到倒排索引中。

ElasticSearch的数据类型

ElasticSearch的数据类型,首先可参考官方文档:

Field data types | Elasticsearch Guide [8.2] | Elastic

从官方文档来看:

基础类型:

  • binary :编码为Base64字符串的二进制值。
  • boolean:布尔类型,true 或 false
  • keywords:关键字家族,包括关键字keyword、常量关键字constant_keyword、通配符wildcard
  • 数字类型:包括了 byte、short、integer、long、float、double、half_float、scaled_float

时间类型:包含了 date 和 date_nanos

别名类型:为现有字段定义别名。

对象和关系类型:

  • object:一个 JSON 对象
  • flattened:整个 JSON 对象作为单个字段值。
  • nested:保留其子字段之间关系的 JSON 对象。
  • join:为同一索引中的文档定义父/子关系。

结构化数据类型:

  • Range:范围类型,例如 long_range、double_range、date_range 和 ip_range。
  • ip:IPv4 and IPv6 addresses.
  • version:软件版本。支持语义版本控制优先规则。
  • murmur3:计算和存储值的哈希值。

聚合数据类型:

  • aggregate_metric_double:预先汇总的指标值。
  • histogram:直方图形式的预聚合数值。

文本搜索类型:

  • text fields:文本系列,包括 text 和 match_only_text。分析的非结构化文本。
  • annotated-text:包含特殊标记的文本。用于识别命名实体。
  • completion:用于自动完成建议。
  • search_as_you_type:键入时完成的类似文本的类型。
  • token_count:文本中标记的计数。

文档排名类型:

  • dense_vector:记录浮点值的密集向量。
  • rank_feature:记录数字特征以在查询时提高命中率。
  • rank_features:记录数字特征以在查询时提高命中率。

空间数据类型:

  • geo_point:纬度和经度点。
  • geo_shape:复杂的形状,例如多边形。
  • point:任意笛卡尔点。
  • shape:任意笛卡尔几何。

其他类型:

percolator:索引用 Query DSL 编写的查询。

数组类型:在 Elasticsearch 中,数组不需要专用的字段数据类型。默认情况下,任何字段都可以包含零个或多个值,但是,数组中的所有值必须是相同的字段类型。请参阅数组。

多领域:

出于不同目的以不同方式索引同一字段通常很有用(使用不同的分词器)。例如,字符串字段可以映射为全文搜索的文本字段,以及排序或聚合的关键字字段。或者,您可以使用标准分析器、英语分析器和法语分析器来索引文本字段。
这就是多领域的目的。大多数字段类型通过 fields 参数支持多字段。

字符串类型总结:text,keyword

elasticsearch之type基本操作

elasticsearch中的type,相当于sql中的数据表,另外表是有结构的,所以在创建表时要指定结构,es中的表结构指mapping。注意,在es6.0以后的版本,只支持一个type,也就是type名称默认为 _mappings,不再有其他别名,所操作的都是 _mappings 这个 type。

(案例使用到了 ik 分词,需要先安装 ik 分词器插件)

elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.2.0/elasticsearch-analysis-ik-8.2.0.zip

新建mapping的数据格式为:

PUT index_name/_mappings
{
    "properties": {
		"content": {
			"analyzer": "ik_max_word",
			"type": "text",
			"fields": {
				"keyword": {
					"ignore_above": 256,
					"type": "keyword"
				}
			}
		},
		"relation": {
			"type": "nested"
		},
		"params": {
			"type": "object"
		},
		"time": {
			"type": "date",
			"format": "epoch_millis"
		}
	}

}

(时间日期,可指定多种类型 ,如:yyyy-MM-dd HH:mm:ss|| epoch_millis)

查询所有的type,使用 pretty 时显示 index 和 type 的关系

curl -XGET "http://localhost:9200/_mapping?pretty=true"

删除一个mapping(type)

似乎是不可以删除mapping的,可以把index删除重建(或新建mapping),此时mapping也跟着删除了。

curl -X DELETE localhost:9200/index_name?pretty

对mapping添加字段:

添加字段时,方式与新增一致,也使用 put 把新的mapping添加字段添加到 index 中即可。

对于修改字段类型、删除mapping等操作,都需要创建一个新的index,并按照新的type同步索引,是比较麻烦的,所以索引的建立应该思考确定后再提交,不要频繁更换。

如果创建新的index太费劲,也可以考虑创建新的 mapping,并为该字段同步数据,即可得到想要的数据,旧的mapping不管它即可。

elasticsearch之index基本操作

查询所有的index(index相当于sql中的数据库)

curl "localhost:9200/_cat/indices?v"

如果执行成功,则返回例如:

health status index                           uuid                   pri rep docs.count docs.deleted store.size pri.store.size

green  open   wr_index_1                      cdI0seyjTF2tgV0qqSiFyg   3   1          2            0     13.9kb          6.9kb
green  open   hbase2es                        fK0TeN9zQemltXq3D29z7Q   1   1    1187578       100000    418.6mb        209.3mb
green  open   gcba0_202108                    eRkEpPP9RNeM30A7KBITzA  18   0          5            0     20.5kb         20.5kb
green  open   dcba0_202108                    q0Sq_wqEQc--K7fURhmmow  18   0          5            0     24.5kb         24.5kb

创建一个索引:(其中doc表示文档,创建一个文档index,而?pretty是美化响应结果数据为Json)

curl -X PUT localhost:9200/doc?pretty

默认情况下新增的索引分片数是1,副本数是1,也就是pri为1,rep为1

更新一个index,仍然使用put,其中 put 的地址:

http://127.0.0.1:9200/doc/_settings

put的参数(json格式):

{
"number_of_replicas": 3
}

删除一个index

curl -X DELETE localhost:9200/doc?pretty

创建完索引后可能处于关闭状态,如果想进行其他操作,应该把它打开

curl -X POST localhost:9200/doc/_open

smarty模板引擎强制编译

默认情况下,模板会进行缓存,如果不希望模板进行缓存,

$smarty->force_compile = true;

另外,可以使用 nocache 局部禁止缓存

{nocache}
  {*通过{nocache}标签进行无缓存设置 *}
  {$smarty.now|date_format}
{/nocache}
  {*通过nocache属性进行无缓存设置*}
{$smarty.now|date_format nocache}

另外在开发模式时,尽量不要缓存,可为程序自定义一个debug模式,如果开启该模式则强制编译。

php 引用变量与数组引用遍历

php数组遍历默认是值传递而不是引用。

在变量赋值时,任意变量均可引用:

<?php

    // 数组引用
    $arr = array("a","b");

    $b = & $arr;

    $b['c'] = "c";

    var_dump($b);

    echo "<br>";

    var_dump($arr);  // 0->"a",1->"b","c"->"c"

    echo "<br>";

    // 基本对象引用
    $a = 2;

    $aa = & $a;

    $aa = 3;

    echo $a;
  // 3
  

使用以下语法让php遍历引用一个数组:

foreach ( $array as & $value ) {

实例:

<?PHP
 $authors = array( "Java", "PHP", "CSS", "HTML" ); 
 foreach ( $authors as  & $val ) { 
   if ( $val == "CSS" ) $val = "Javascript"; 
   echo $val . " "; 
 } 
 unset( $val ); 
 print_r ( $authors );   
?>

注意:

$unset($val) 确保 $val 变量在循环已完成。

当循环结束时,$ val仍然保存对最后一个元素的引用。在我们的代码中更改$ val改变$ authors数组的最后一个元素。通过取消设置$ val,我们避免潜在的错误。

PHP define 和 const定义常量

php 定义常量有2种方式,

define("ROOT",$root);  // 定义一个 ROOT 常量,默认为全局

另一种方法是:

const ROOT $root;  // 也是定义一个常量

如果想给一个类定义常量,则只能使用 const

另外 PHP 的全局常量,是不需要 global 引入的,而是一个方法中引入全局变量则需要使用 global 关键字引入 ,这就使得PHP常量用的比其他语言要频繁。