首页 Elasticsearch

elasticsearch-php 快速入门


安装

环境要求

  • 大于等于php7.1
  • 需要安装composer
  • 需要CURL扩展
  • 原生JSON扩展(ext-json) 1.3.7或更高

通过composer安装

composer require elasticsearch/elasticsearch

连接

通过Http认证方式初始化

$hosts = [
    'http://user:pass@localhost:9200',  // 一定要加端口号,不然有可能会连接失败,即便是80端口也要添加
]; 

$client = ClientBuilder::create()
                    ->setHosts($hosts)
                    ->setRetries(2)  # 重试连接次数
                    ->setElasticMetaHeader(false) # 禁止在header头中发送es服务信息
                    ->build();

新建一个文档

指定文档id创建

我们需要指定三段信息:索引(索引不存在时会自动创建)、id和文档主体。这是通过构造键:值对的关联数组来实现的。请求体本身就是一个关联数组,键:值对对应于文档中的数据:

$params = [
    'index' => 'my_index',
    'id'    => 'my_id',
    'body'  => ['testField' => 'abc']
];

$response = $client->index($params);
print_r($response);

# 返回值
Array
(
    [_index] => my_index # 索引
    [_type] => _doc             # 文档类型
    [_id] => my_id             # 文档id
    [_version] => 1             # 文档版本号
    [created] => 1             
)

自动生成id方式创建

$params = [
    'index' => 'my_index',
    'body'  => ['testField' => 'abc']
];

$response = $client->index($params);
print_r($response);

创建文档其他的参数

$params = [
    'index'     => 'my_index',
    'id'        => 'my_id',
    'routing'   => 'company_xyz',
    'timestamp' => strtotime("-1d"),
    'body'      => [ 'testField' => 'abc']
];

$response = $client->index($params);

批量创建索引

for($i = 0; $i < 100; $i++) {
    $params['body'][] = [
        'index' => [
            '_index' => 'my_index',
        ]
    ];

    $params['body'][] = [
        'my_field'     => 'my_value',
        'second_field' => 'some more values'
    ];
}

$responses = $client->bulk($params);

上边组成的数组格式就类似于这样:

array:1 [▼
  "body" => array:2 [▼
    0 => array:1 [▼
      "index" => array:1 [▼
        "_index" => "wiki"
      ]
    ]
    1 => array:3 [▼
      "id" => "2"
      "title" => "这是批量插入的"
      "description" => "测试一下批量插入的"
    ]
    2 => array:1 [▼
      "index" => array:1 [▼
        "_index" => "wiki"
      ]
    ]
    3 => array:3 [▼
      "id" => "2"
      "title" => "这是批量插入的"
      "description" => "测试一下批量插入的"
    ]
  ]
]

获取一个文档

通过id获取一个文档

$params = [
    'index' => 'my_index',
    'id'    => 'my_id'
];

$response = $client->get($params);
print_r($response);
# 返回结果
Array
(
    [_index] => my_index    # 索引
    [_type] => _doc                # 文档类型
    [_id] => my_id                # 文档id
    [_version] => 1                # 文档版本号
    [found] => 1
    [_source] => Array        # 文档内容
        (
            [testField] => abc
        )

)

更新文档

更新文档允许您完全替换现有文档的内容,或者只对一些字段执行部分更新(更改现有字段或添加新字段)。

部分更新

$params = [
    'index' => 'my_index',
    'id'    => 'my_id',
    'body'  => [
        'doc' => [
            'new_field' => 'abc'  # 需要更新的字段
        ]
    ]
];

$response = $client->update($params);

脚本化更新

有时您需要执行脚本化的更新,例如递增计数器或向数组添加新值。要执行脚本更新,您需要提供一个脚本

$params = [
    'index' => 'my_index',
    'id'    => 'my_id',
    'body'  => [
        'script' => 'ctx._source.counter += count',  # 需要执行的脚本
        'params' => [
            'count' => 4
        ]
    ]
];

$response = $client->update($params);

upserts参数

Upserts是“更新或插入”操作。这意味着upsert会尝试运行您的更新脚本,但是如果文档不存在(或者您试图更新的字段不存在),则会插入默认值。

$params = [
    'index' => 'my_index',
    'id'    => 'my_id',
    'body'  => [
        'script' => [
            'source' => 'ctx._source.counter += params.count',
            'params' => [
                'count' => 4
            ],
        ],
        'upsert' => [
            'counter' => 1
        ],
    ]
];

$response = $client->update($params);

删除文档

删除指定id的文档

$params = [
    'index' => 'my_index',
    'id'    => 'my_id'
];

$response = $client->delete($params);

搜索

简单的列子

$params = [
    'index' => 'my_index',
    'body'  => [
        'query' => [
            'match' => [
                'testField' => 'abc'
            ]
        ],
        'highlight' => array[
          'fields' => array[
              'content' => new \stdClass() # 如果参数中想传入个空的话,必须这样写
          ]
        ]
    ]
];

$response = $client->search($params);
print_r($response);
# 返回结果
Array
(
    [took] => 1
    [timed_out] =>
    [_shards] => Array
        (
            [total] => 5
            [successful] => 5
            [failed] => 0
        )

    [hits] => Array
        (
            [total] => 1                                # 有几条数据
            [max_score] => 0.30685282
            [hits] => Array                            #返回的搜索文档的结果
                (
                    [0] => Array
                        (
                            [_index] => my_index
                            [_type] => _doc
                            [_id] => my_id
                            [_score] => 0.30685282                # 匹配分数,分数越高越靠前
                            [_source] => Array
                                (
                                    [testField] => abc
                                )
                        )
                )
        )
)

match匹配搜索

$params = [
    'index' => 'my_index',        # 指定索引
    'body'  => [
        'query' => [
            'match' => [
                'testField' => 'abc'        # 字段匹配条件
            ]
        ]
    ]
];

$results = $client->search($params);

使用原始json方式请求

有时,为了测试目的或者从不同的系统迁移时,使用原始JSON很方便。你可以在body中使用raw JSON作为字符串,客户端会自动检测到这一点

$json = '{
    "query" : {
        "match" : {
            "testField" : "abc"
        }
    }
}';

$params = [
    'index' => 'my_index',
    'body'  => $json
];

$results = $client->search($params);

bool查询

$params = [
    'index' => 'my_index',
    'body'  => [
        'query' => [
            'bool' => [
                'must' => [
                    [ 'match' => [ 'testField' => 'abc' ] ],
                    [ 'match' => [ 'testField2' => 'xyz' ] ],
                ]
            ]
        ]
    ]
];

$results = $client->search($params);

复杂案例

$params = [
    'index' => 'my_index',
    'body'  => [
        'query' => [
            'bool' => [
                'filter' => [ # 过滤查询
                    'term' => [ 'my_field' => 'abc' ]
                ],
                'should' => [
                    'match' => [ 'my_other_field' => 'xyz' ]
                ]
            ]
        ]
    ]
];


$results = $client->search($params);

删除一个文档

$params = [
    'index' => 'my_index',
    'id'    => 'my_id'
];

$response = $client->delete($params);
print_r($response);
# 返回结果
Array
(
    [found] => 1
    [_index] => my_index
    [_type] => _doc
    [_id] => my_id
    [_version] => 2
)

删除文档

$deleteParams = [
    'index' => 'my_index'
];
$response = $client->indices()->delete($deleteParams);
print_r($response);
# 返回结果
Array
(
    [acknowledged] => 1
)

新建索引

简单列子

$params = [
    'index' => 'my_index',
    'body' => [
        'settings' => [
            'number_of_shards' => 2,
            'number_of_replicas' => 0
        ],
        'mappings' => [
              '_source' => [
                  'enabled' => true
              ],
              'properties' => [
                  'first_name' => [
                      'type' => 'keyword'
                  ],
                  'age' => [
                      'type' => 'integer'
                  ]
              ]
          ]
    ]
];

$response = $client->indices()->create($params);
print_r($response);
# 返回结果
Array
(
    [acknowledged] => 1
)

复杂案例

$params = [
    'index' => 'reuters',
    'body' => [
        'settings' => [  # 设置包含关于索引(分片的编号等)和分析器的配置。
            'number_of_shards' => 1,
            'number_of_replicas' => 0,
            'analysis' => [ # 分析嵌套在设置中,并包含标记器、过滤器、字符过滤器和分析器。
                'filter' => [
                    'shingle' => [
                        'type' => 'shingle'
                    ]
                ],
                'char_filter' => [
                    'pre_negs' => [
                        'type' => 'pattern_replace',
                        'pattern' => '(\\w+)\\s+((?i:never|no|nothing|nowhere|noone|none|not|havent|hasnt|hadnt|cant|couldnt|shouldnt|wont|wouldnt|dont|doesnt|didnt|isnt|arent|aint))\\b',
                        'replacement' => '~$1 $2'
                    ],
                    'post_negs' => [
                        'type' => 'pattern_replace',
                        'pattern' => '\\b((?i:never|no|nothing|nowhere|noone|none|not|havent|hasnt|hadnt|cant|couldnt|shouldnt|wont|wouldnt|dont|doesnt|didnt|isnt|arent|aint))\\s+(\\w+)',
                        'replacement' => '$1 ~$2'
                    ]
                ],
                'analyzer' => [
                    'reuters' => [
                        'type' => 'custom',
                        'tokenizer' => 'standard',
                        'filter' => ['lowercase', 'stop', 'kstem']
                    ]
                ]
            ]
        ],
        'mappings' => [     # Mappings是嵌套在设置中的另一个元素,它包含各种类型的映射。
            'properties' => [
                'title' => [
                    'type' => 'text',
                    'analyzer' => 'reuters',
                    'copy_to' => 'combined'
                ],
                'body' => [
                    'type' => 'text',
                    'analyzer' => 'reuters',
                    'copy_to' => 'combined'
                ],
                'combined' => [
                    'type' => 'text',
                    'analyzer' => 'reuters'
                ],
                'topics' => [
                    'type' => 'keyword'
                ],
                'places' => [
                    'type' => 'keyword'
                ]
            ]
        ]
    ]
];
$client->indices()->create($params);

删除索引

$params = ['index' => 'my_index'];
$response = $client->indices()->delete($params);

修改索引

$params = [
    'index' => 'my_index',
    'body' => [
        'settings' => [
            'number_of_replicas' => 0,
            'refresh_interval' => -1
        ]
    ]
];

$response = $client->indices()->putSettings($params);

查询一个或多个索引

查询一个索引

$params = ['index' => 'my_index'];
$response = $client->indices()->getSettings($params);

查询多个索引

$params = [
    'index' => [ 'my_index', 'my_index2' ]
];
$response = $client->indices()->getSettings($params);

给已存在的索引添加mappings

$params = [
    'index' => 'my_index',
    'body' => [
        '_source' => [
            'enabled' => true
        ],
        'properties' => [
            'first_name' => [
                'type' => 'text',
                'analyzer' => 'standard'
            ],
            'age' => [
                'type' => 'integer'
            ]
        ]
    ]
];

$client->indices()->putMapping($params);

获取索引的mappings

// 获取所有的
$response = $client->indices()->getMapping();

// 获取指定一个的
$params = ['index' => 'my_index'];
$response = $client->indices()->getMapping($params);

// 获取指定多个的
$params = [
    'index' => [ 'my_index', 'my_index2' ]
];
$response = $client->indices()->getMapping($params);



文章评论

目录