1.创建索引 见官方文档:索引文档 | Elasticsearch: 权威指南 | Elastic
1.1单个创建
PUT /{index}/{type}/{id}
{
"field": "value",
...
}
案例 website表示 索引的名字 bllog 表示 索引下面的分类 , 123 表示索引的id ,举例 比如 一个点上系统里面的产品 ,分类有 电子产品 ,我们就可以 索引的名字叫 product,
type 叫electronic
PUT /website/blog/123
{
"title": "My first blog entry",
"text": "Just trying this out...",
"date": "2014/01/01"
}
1.2在指定的索引和type 下面创建
比如在index user ,type api 下面创建 id 为 345 的索引
POST /user/api/345 HTTP/1.1
Host: localhost:9200
Content-Type: application/json
Content-Length: 73
{"age":15,"username":"huang","gender":"man","desc":"i am a strong man"}
插入成功后,我们用id取回
1.3批量创建
使用postman
POST /_bulk HTTP/1.1
Host: localhost:9200
Content-Type: application/json
Content-Length: 538
{ "index" : { "_index" : "product","_type":"number", "_id" : "40372399b5596341bb5b63f3bf09c502" } }
{ "seri_number" : "1100614626" }
{ "index" : { "_index" : "product","_type":"number", "_id" : "a05277598f75d66a900ab458701adbc7" } }
{ "seri_number" : "549197690" }
{ "index" : { "_index" : "product","_type":"number", "_id" : "6d88f094bf4e4b31984b7ad8bd32bdf7" } }
{ "seri_number" : "514706614" }
{ "index" : { "_index" : "product","_type":"number", "_id" : "71b74e4624b622d6f5053514344cbc87" } }
{ "seri_number" : "1778533480" }
注意数据最后一定要加多一个回车换行,不然会提示失败
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "The bulk request must be terminated by a newline [\\n]"
}
],
"type": "illegal_argument_exception",
"reason": "The bulk request must be terminated by a newline [\\n]"
},
"status": 400
}
php 调用curl 批量插入索引代码
<?php
//elastic批量插入
ini_set('memory_limit','1024M');
function getRandHanzi($num){
$result = '';
$hanziSource = '丰王井开夫天元无云专扎艺木五支厅不太犬区历友尤匹车巨牙屯比互切瓦止少日中贝内水冈见手午牛毛气升长仁什片仆化仇币仍仅斤爪反介父从今凶分乏公仓月氏勿风欠丹匀乌勾凤六文方火为斗忆计订户认心尺引丑巴孔队办以允予劝双书幻玉刊末未示击打巧正扑扒功扔去甘世古节本术可丙左厉石右布龙平灭轧东卡北占业旧帅归目旦且叮叶甲申号电田由只央史兄叼叫叨另叹四生失禾丘付仗代仙们仪白仔他斥瓜乎丛令用甩印乐句匆册犯外处冬鸟务包饥主市立闪兰半汁汇头汉宁穴它讨写让礼训必议讯记永司尼民出辽奶奴加召皮边孕发圣对台矛纠母幼丝式刑动扛寺吉扣考托老圾巩执扩扫地扬场耳共芒亚芝朽朴机权过臣再协西压厌在百有存而页匠夸夺灰达列死成夹轨邪划迈毕至此贞师尘尖劣光当早吐吓虫曲团同吊吃因吸吗屿帆岁回岂则刚网肉年朱先丢舌竹迁乔伟传乒乓休伍伏优伐延件任伤价份华仰仿伙伪自血向似后行舟全会杀合兆企众爷伞创肌朵杂危旬旨负各名多争色壮冲冰庄庆亦刘齐交次衣产决充妄闭问闯羊并关米灯州汗污江池汤忙兴宇守宅字安讲军许论农讽设访寻那迅尽导异孙阵阳收阶阴防奸如妇好她妈戏羽观欢买红纤约级纪驰巡寿弄麦形进戒吞远违运扶抚坛技坏扰拒找批扯址走抄坝贡攻赤折抓扮抢孝均抛投坟坑抗坊抖护壳志块扭声把报却劫芽花芹芬苍芳严芦劳克苏杆杜杠材村杏极李杨求更束豆两丽医辰励否还歼来连步坚旱盯呈时吴助县里呆园旷围呀吨足邮男困吵串员听吩吹呜吼吧别岗帐财钉针告我乱利秃秀私每兵估体何但伸作伯伶佣低你住位伴身皂佛近彻役返余希坐谷妥含邻岔肝肚肠龟免狂犹角删条卵岛迎饭饮系言冻状亩况床库疗应冷这序辛弃冶忘闲间闷判灶灿弟汪沙汽沃泛沟没沈沉怀忧快完宋宏牢究穷灾良证启评补初社识诉诊词译君灵即层尿尾迟局改张忌际陆阿陈阻附妙妖妨努忍劲鸡驱纯纱纲纳纵驳纷纸纹纺驴纽';
$hanziSourceLen = strlen($hanziSource);
for($i=0;$i<$num;$i++){
$starLoc = 3* rand(0,$hanziSourceLen/3);
$tempHanzi = $hanziSource[$starLoc].$hanziSource[$starLoc+1].$hanziSource[$starLoc+2];
$result.=$tempHanzi;
}
return $result;
}
function randLetter($num){
$str = 'abcdefghijklmnopqrstuvwxyz';
$result = '';
for($i=0;$i<($num);$i++){
$result .= $str[rand(0,26)];
}
return $result;
}
for($j=0;$j<1000;$j++){
$curl = curl_init();
$template = '{ "index" : { "_index" : "product","_type":"number", "_id" : "#id" } }
{ "seri_number" : "#number" ,"username":"#username"}'."\n";
$stime = time();
$putStr ='';
for($i=0;$i<100000;$i++){
$id = md5(time().microtime().rand(1,1000000000));
$number = getRandHanzi(10);
$indexInsert = str_replace('#id',$id,$template);
$indexInsert = str_replace('#number',$number,$indexInsert);
$indexInsert = str_replace('#username',randLetter(10),$indexInsert);
if($i==0 || $i ==1){
echo $indexInsert;
}
$putStr.= $indexInsert;
}
curl_setopt_array($curl, array(
CURLOPT_URL => 'http://localhost:9200/_bulk',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $putStr,
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json'
),
));
$response = curl_exec($curl);
curl_close($curl);
//echo $response;
echo 'success';
echo "\n";
echo time() - $stime;
}
2.查询索引
2.1 根据id查询 ,明确索引和类型的情况下
http://localhost:9200/product/number/4ac527c56f19c76dbf58db9e543bd12b?pretty
product 表示的索引
number 表示的是type
4ac527c56f19c76dbf58db9e543bd12b 表示的是id
2.2根据id 查询 ,不知道 索引和类型的情况下
贴出postman ,http协议 的代码:
POST /_search?pretty=null HTTP/1.1
Host: localhost:9200
Content-Type: application/json
Content-Length: 112
{
"query": {
"term": {
"_id": "17af009cffb2080415711e07b97b18f0"
}
}
}
在不知道 索引和 类型的情况下 我们是用url:
http://localhost:9200/_search?pretty
很多时候 我们是知道索引的
http://localhost:9200/product/_search?pretty #product指的是索引的名字
知道索引和 类型 的时候
http://localhost:9200/product/electronic/_search?pretty #product指的是索引的名字 ,electronic 是类型的名字
2.3 根据文档里面字段的范围查询
POST /user/api/_search HTTP/1.1
Host: localhost:9200
Content-Type: application/json
Content-Length: 285
{
"query" : {
"constant_score" : {
"filter" : {
"range" : {
"age" : {
"gte" : 15,
"lt" : 16
}
}
}
}
}
}
2.4根据 date 的范围查询
{
"query" : {
"constant_score" : {
"filter" : {
"range" : {
"date" : {
"gte" : "2018/01/01 12:10:32",
"lt" : "2022/01/01 12:10:32"
}
}
}
}
}
}
2.5 查询某个索引下面的所有的数据
GET /user/_search HTTP/1.1
Host: localhost:9200
2.6 查询某个索引下面的所有的数据 支持分页查询 和限定查询多少条目
GET /product/_search?pretty=null&size=500&from=0 HTTP/1.1
Host: localhost:9200
2.7 查询 某个字段多个值 类似 mysql where in
{
"query" : {
"constant_score" : {
"filter" : {
"terms" : {
"username" : ["huang11","google"]
}
}
}
}
}
2.8 查询单个值 ,类似mysql 的 where xx=xx
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"username" : "google"
}
}
}
}
}
2.9 多个条件组合查询 类似mysql where a in (1,2) and b in(34) and c =1
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [
{
"term": {
"gender": "female"
}
},
{
"terms": {
"username": [
"google"
]
}
},
{
"terms": {
"age": [
"40"
]
}
},
{
"range": {
"age": {
"gte": 30,
"lt": 41
}
}
},
{
"range": {
"date": {
"gte": "2001/01/01 12:10:32",
"lt": "2022/01/01 12:10:32"
}
}
}
]
}
}
}
}
}
postman http 代码:
POST /user/_search HTTP/1.1
Host: localhost:9200
Content-Type: application/json
Content-Length: 1515
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [
{
"term": {
"gender": "female"
}
},
{
"terms": {
"username": [
"google"
]
}
},
{
"terms": {
"age": [
"40"
]
}
},
{
"range": {
"age": {
"gte": 30,
"lt": 41
}
}
},
{
"range": {
"date": {
"gte": "2001/01/01 12:10:32",
"lt": "2022/01/01 12:10:32"
}
}
}
]
}
}
}
}
}
2.10 多个条件组合查询 and or 组合 如 where a =1 and ( b=1 or b=2)
一下代码 等于 : gender='female' and (age=40 or age=50)
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [
{
"term": {
"gender": "female"
}
},
{
"bool": {
"should": [
{
"term": {
"age": 40
}
},
{
"term": {
"age": 50
}
}
]
}
}
]
}
}
}
}
}
也可以换种写法 (不推荐,太复杂)
{
"query": {
"constant_score": {
"filter": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"gender": "female"
}
},
{
"term": {
"age": 40
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"gender": "female"
}
},
{
"term": {
"age": 50
}
}
]
}
}
]
}
}
}
}
}
2.11 查询组合条件 must not 用法
以下查询 类似 mysql : gender="female" and (age=40 or age=50) and country!='usa'
{
"query": {
"constant_score": {
"filter": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"gender": "female"
}
},
{
"term": {
"age": 40
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"gender": "female"
}
},
{
"term": {
"age": 50
}
}
]
}
}
],
"must_not": [
{
"term": {
"country": "usa"
}
}
]
}
}
}
}
}
2.12 短语查询(类似 php 函数 里面的 strpos )
{
"query": {
"match_phrase": {
"desc": "strong"
}
}
}
post man http 代码
POST /user/api/_search HTTP/1.1
Host: localhost:9200
Content-Type: application/json
Content-Length: 95
{
"query": {
"match_phrase": {
"desc": "strong"
}
}
}
举例 查询 index :user ,type :api 下面的 数据里面 的 desc 自动里面包含 strong 的所有条目
2.13 短语查询,查询日期
比如 有个字段 date ,格式为 2015/01/01 23:45:00
查询 一月1日 的数据 。 (这种做法不推荐 ,还是推荐用range 比较实现 )
{
"query": {
"match_phrase": {
"date": "2015/01/01"
}
}
}
2.14 模糊查询 多种模式
- match
- match_phrase
- match_phrase_prefix
有字段 desc ="我要去北京旅游" , 这个时候搜“北游”” 。
{
"query": {
"xxx": { # xx 取值 match ,match_phrase , match_phrase_prefix
"desc": "北游"
}
}
}
结果如下 :
北游 |
我要去北京旅游 |
match |
命中 |
match_phrase |
无法命中 |
match_phrase_prefix |
无法命中 |
北京 |
我要去北京旅游 |
match |
命中 |
match_phrase |
命中 |
match_phrase_prefix |
命中 |
北方 |
我要去北京旅游 |
match |
命中 |
match_phrase |
不命中 |
match_phrase_prefix |
不命中 |
下面我们试试英文 ,英文分为2种,一种是语句,也就是带空格的 ,用单词匹配 还有就是 一个字符串 连续的没空格 。我们分配做了实验结果如下
搜索串 |
源串 |
love and you |
i love you |
match |
命中 |
match_phrase |
不命中 |
match_phrase_prefix |
不命中 |
搜索串 |
源串 |
love you |
i love you |
match |
命中 |
match_phrase |
命中 |
match_phrase_prefix |
命中 |
love |
i love you |
match |
命中 |
match_phrase |
命中 |
match_phrase_prefix |
命中 |
love she |
i love you |
match |
命中 |
match_phrase |
不命中 |
match_phrase_prefix |
不命中 |
ve |
i love you |
match |
不命中 |
match_phrase |
不命中 |
match_phrase_prefix |
不命中 |
i lov |
i love you |
match |
命中 |
match_phrase |
不命中 |
match_phrase_prefix |
命中 |
i lov |
i love you |
match |
命中 |
match_phrase |
不命中 |
match_phrase_prefix |
命中 |
总结:
1.match 会将 要查询的 关键词 分词 去查询,只要包含了 分词结果种的任意一个 就会命中
2.match_phrase 精确命中模式 ,就是 必须 是一个完整的单词命中 。比如 查询字符串 love you , 则 待查询的字符串里面 必须 包含 love you 这2个单次 切顺序一直 先后顺序 而且要连起来 中间不能有别的单词 ,match_phrase查询分析文本并根据分析的文本创建一个短语查询。match_phrase 会将检索关键词分词。match_phrase的分词结果必须在被检索字段的分词中都包含,而且顺序必须相同,而且默认必须都是连续的。
3. match_phrase_prefix
与match_phrase查询类似,但是会对最后一个Token在倒排序索引列表中进行通配符搜索。Token的模糊匹配数控制:max_expansions 默认值为50。
2.15 模糊查询字符串包含模式
{
"query": {
"wildcard": {
"desc": "*defg*"
}
}
}
比如 源字符串 abcdefghi ,你要查询 包含 defg 的 条目, 使用 match,match_phrase ,match_phrase_prefix 都无用。 就用这个模式
2.16字符串模糊查询和 多条件 term 组合查询 等同 mysql, where xx=xx and ( yy = 1 or yy =2 ) and zz like '%ss%' and !(zz like %dd%)
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [
{
"term": {
"gender": "female"
}
},
{
"bool":{
"must":[
{
"wildcard":{
"username":"*oo*"
}
}
],
"must_not":[
{
"match":{
"desc":"北京"
}
}
]
}
},
{
"bool": {
"should": [
{
"term": {
"age": 40
}
},
{
"term": {
"age": 50
}
}
]
}
}
]
}
}
}
}
}
3.删除索引
假设索引的 index叫: user ,type: api 删除id 为 1e2cd2167de3fa8fb58bbc02a27fcfd9111x 的条目
DELETE /user/api/1e2cd2167de3fa8fb58bbc02a27fcfd9111x HTTP/1.1
Host: localhost:9200
4. 排序 sort
原始数据
{
"took": 0,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 5,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "taobao_product",
"_type": "clothes",
"_id": "pSYT6nwBCml6W84gfRdv",
"_score": 1.0,
"_source": {
"title": "夏天的风衣1",
"desc": " 这是夏天的风衣,很薄,风衣",
"price": 100
}
},
{
"_index": "taobao_product",
"_type": "clothes",
"_id": "piYT6nwBCml6W84gfRdv",
"_score": 1.0,
"_source": {
"title": "夏天的风衣2",
"desc": " 这是夏天的风衣,很薄,风衣",
"price": 200
}
},
{
"_index": "taobao_product",
"_type": "clothes",
"_id": "pyYT6nwBCml6W84gfRdv",
"_score": 1.0,
"_source": {
"title": "冬天的风衣1",
"desc": " 这是冬天天的风衣,很厚",
"price": 600
}
},
{
"_index": "taobao_product",
"_type": "clothes",
"_id": "qCYT6nwBCml6W84gfRdw",
"_score": 1.0,
"_source": {
"title": "冬天的风2",
"desc": " 这是冬天的风衣,很后",
"price": 500
}
},
{
"_index": "taobao_product",
"_type": "clothes",
"_id": "qSYd6nwBCml6W84geBcd",
"_score": 1.0,
"_source": {
"title": "夏天的时尚衣服",
"desc": " 这是夏天的风衣,很薄,风衣,风衣风衣",
"price": 100
}
}
]
}
}
执行查询
{
"query": {
"bool": {
"should": [
{
"match": {
"title": {
"query": "冬天天风衣",
"boost": 2
}
}
},
{
"match": {
"desc": {
"query": "夏天风衣",
"boost": 1
}
}
}
]
}
},
"sort": [
{
"price": {
"order": "desc"
}
}
]
}
boost 控制权重