php使用ElasticSearch

laravel 连接ES

1、安装扩展包
composer require laravel/scout
composer require tamayo/laravel-scout-elastic
composer require Guzzlehttp/guzzle
2、在 config/app.php 的 providers 数组添加:
Laravel\Scout\ScoutServiceProvider::class,
ScoutEngines\Elasticsearch\ElasticsearchProvider::class,
3、发布配置文件:
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
发布生成的 config/scout.php 文件添加
 'driver' => env('SCOUT_DRIVER', 'elasticsearch'),
    'elasticsearch' => [
        'index' => env('ELASTICSEARCH_INDEX', 'laravel'),//索引名称
        'hosts' => [
            env('ELASTICSEARCH_HOST', 'http://127.0.0.1:9200'),
        ],
    ],
4、连接es,增删改查
	新建一个测试接口
	use Elasticsearch\ClientBuilder;
	
	public $client = null;
    public function __construct()
    {
        $this-> client = ClientBuilder::create()->build();
    }
    
    $this->client->create()   [update\get\delete]
    
    
    参考文档
    https://learnku.com/articles/30812
	https://blog.csdn.net/qq_29677867/article/details/92839388

解释ES

Elasticsearch 是一个基于 Lucene 的搜索引擎。它提供了具有 HTTP Web 界面和无架构 JSON 文档的分布式,多租户能力的全文搜索引擎。
Elasticsearch 是用 Java 开发的,根据 Apache 许可条款作为开源发布。

映射关系
- 其就是对创建索引的时候给字段建立类型,随后要插入的字段必须遵循以定义好的字段类型进行插入
- keyword类型不能被分词,text可以被分词

倒排索引

ES是一个倒排索引进行检索的
倒排索引指的是:通过关键字,查询主键id,随后查询关联的内容 

es的关系理解

索引 ---- 数据库

类型 ----- 数据表

文档 -----  行

字段 ------   列

基础命令

PUT  	localhost:9200/索引名称/类型名称/文档id	   		 														创建(指定id)文档
POST	localhost:9200/索引名称/类型名称				  														 创建(随机id)文档
POST	localhost:9200/索引名称/类型名称/文档id/_update	 														修改文档
DELETE	localhost:9200/索引名称/类型名称/文档id			 														删除文档
GET	    localhost:9200/索引名称/类型名称/文档id			 														查询文档
POST	localhost:9200/索引名称/类型名称/_search	      														 查询所有数据
GET		127.0.0.1:9200/索引名称/_analyze  {"analyzer":"ik_max_word","text":"asd泡面很好吃"}				   		 查看分词器
POST	127.0.0.1:9200/索引名称/_reindex  				   														复制索引及内容
    {
      "source": {
        "index": "dwk1_item_index"  //旧索引
      },
      "dest": {
        "index": "dwk1_copy_item_index", //新索引
        "op_type": "create"
      }	
    }
 POST	127.0.0.1:9200/索引名称/_aliases  				   														设置别名
 {
        "actions": [
            {"add": {"index": "my_index2", "alias": "my_index"}}
        ]
  }

最普通的查询

//最普通的查询是全文检索,只要你的关键词存在,则匹配
{
	"query":{
		"match":{
			"字段":{
				"query":"我是帅哥"
			}
		}
	}
}

限定返回字段查询:

GET /索引名/类型名/_search
{
	"_source": ["字段1","字段2"]
}

排序查询:

  • 排序字段必须为long类型
GET /索引名/类型名/_search
{
	"sort": [
    {
      "FIELD": {
        "order": "desc"
      }
    }
  ]
}

分页查询:

GET /索引名/类型名/_search
{
  "query": {},
  "from": 0,
  "size": 20
}

bool查询:

  • 所有的条件查询都可以基于bool查询,也就是bool里面写其他的条件查询
关键字								描述
must					必须匹配, 相当于mysql中的and
should					至少有一个匹配, 相当于mysql中的or
must_not				必须不匹配,相当于mysql中的not
filter					条件过滤   相当于must 
GET /索引名/类型名/_search
{
  "query": {
    "bool": {
      "must": [   //关键字
        {
          "match": {
            "FIELD": "TEXT"   //字段 : 值
          }
        },
        {
          "match": {
            "FIELD": "TEXT"
          }
        }  
      ]
    }
  }
}

精确查询

//前提条件keyword类型
{
  "query": {
  “bool”:{
  		"must":[{
  			 "term": {
          		"字段": "字段1值 
          		}
  			}
  		}]
  }
}
// text类型时的等值查询
{
  "query": {
  “bool”:{
  		"must":[{
  			 "match_phrase  ": {
          		"字段": "字段1值 
          		}
  			}
  		}]
  }

范围查询

gte:大于等于
gt:大于
lte:小于等于
lt:小于
boost:设置查询的推动值(boost),默认为1.0
//数值范围查询,必须使用long类型
{
    "query": {
        "range" : {
            "字段" : {
                "gte" : 2,
                "lt" :  100
            }
        }
    }
}
//时间日期范围查询
//必须为时间类型字段:
 "endTime": {
           "type": "date",
           "ignore_malformed": true,
           "format": "yyyy-MM-dd HH:mm:ss"
	}
//查询语法:
{
    "query": {
        "range" : {
            "字段" : {
                "gte" : 2,
                "lt" :  100,
                'format'=>'yyyy-MM-dd HH:mm:ss'
            }
        }
    }
}

数组查询

//当保存的字段为数组时例如:
"category": [
        "135835",
        "112870",
        "135839"
]	
//查询语法
{
    "query": {
        "term" : {
            "字段" : {
               "value":135835
            }
        }
    }
}

多字段模糊查询

  • 用于一个值模糊匹配多个规定的字段

    {
    "query": {
    		"bool": {
    			"should": [{
    				"multi_match": {
    					"query": "IDC",
    					"fields": ["form_name", "form_title", "form_serial"]
    				}
    			}]
    		}
    	}
    }
    

聚合查询

//分组查询
{
	"aggs":{  //聚合操作
		"别名":{  //随意起名字
			"terms":{   //分组,这里有很多聚合函数,例如avg terms sum等具体可以百度
				"field":{
					"字段名"
				}
			}
		}
	}
}

分词器

// 字段设置分词器,前提条件必须是text类型,keyword类型不能被分词
{
  "mappings":{
   "properties": {
   		"title": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    },
                    "analyzer" : "ik_max_word",  
                    "search_analyzer": "ik_max_word",
                    "index" : true
       }
   	}
  }
}
IK分词器包含两种analyzer,一般用ik_max_word

ik_max_word:会将文本做最细粒度的拆分

ik_smart:会做最粗粒度的拆分

// 设置搜索关键字权重
{
"query": {
		"bool": {
			"should": [{
				"multi_match": {
					"query": "IDC",
					"fields": ["form_name", "form_title", "form_serial"],
					"minimum_should_match":100%
				}
			}]
		}
	}
}

批量操作

  • 批量操作可以一次性操作多条数据,它是把请求在加载到子节点里,所有批量的越多请求越大,可以根据服务器的大小来确定一个最大值,正常一次性文档数量最大为:1000—5000个,或者5-15M
  • 好处就是相同的文档id不会重复插入,即就是文档id唯一
// 批量修改
 {
       "update": {
            "_index": "test_dwk_item_index",  //索引名
            "_id": "44980567"    //文档id,可以自己定义的
       }
 },
 {
      "doc": {    //文档值
           "promotion_wording": "哈哈",   //具体修改字段
           "user_id": "24",
           "goodsTime": 1628082800
       }
 }
 //php 格式,多个请用循环
   				$res['body'][] = [
                    'update'=>[
                        '_index'=> env('ELASTICSEARCH_INDEX'),
                        '_id'=> $v['productId'],
                    ],
                ];             
                $res['body'][] = [
                    'doc'=>[
                        'productId'=>intval($v['productId']),
                        'productIds'=>strval($v['productId']),
                        'user_id'=>$user_id,
                        'goodsTime'=>strtotime($goodsTime->created_at)
                    ]
                ];
 // 如果是多个,重复上面的格式操作
 
 // 批量添加
  {
       "create": {  //或者index也行
            "_index": "test_dwk_item_index",  //索引名
            "_id": "44980567"    //文档id
       }
 },
 {
      "promotion_wording": "哈哈",   //具体修改字段
      "user_id": "24",
      "goodsTime": 1628082800
 }
 //php 格式,多个请用循环
  				$res['body'][] = [
                    'create'=>[
                        '_index'=> env('ELASTICSEARCH_INDEX'),
                        '_id'=> $v['productId'],
                    ],
                ];
                $res['body'][] = [
                    'productId'=>intval($v['productId']),
                    'endTime'=>date('Y-m-d H:i:s',time() + (60*60*24*365)),
                    'goodsTime'=>time()
                ];
 // 如果是多个,重复上面的格式操作,对比更新,创建则不需要”doc“
 
 // 批量删除
  {
       "delete": {  
            "_index": "test_dwk_item_index",  //索引名
            "_id": "44980567"    //文档id
       }
 }
 ................

在bool中must和should条件同时满足

{
    "query": {
        "bool": {
            "must": [
                {"term": {"color": "red"}}
            ],
            #当must存在的时候,should中的条件是可有可无的,就是must条件满足就行,should的一个都不用满足也可以
            #当must不存在的时候,should中的条件至少要满足一个
            "should": {
                {"term": {"size": 33}},
                {"term": {"size": 55}}
            },
            #所以当must存在,又想让should的条件至少满足一个地加这个参数
            #也可以再must》term统计再加一个bool》must》should
            "minimum_should_match":1       //这个比较实用
        }
    }
}

//代码实现
$goodsCats = json_decode(Redis::get('goodsCatsLogs'),true);
$goodsCats = array_column($goodsCats,$pan['categoryId']);
if(isset($goodsCats) && !empty($goodsCats)){
    foreach ($goodsCats as $k => $v){
        $body['query']['bool']['should'][]['term']['category'] = ['value'=>strval($v)];
    }
  }
$body['query']['bool']['minimum_should_match'] = 1;   //至少生效一个条件或多个
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值