索引文档

未匹配的标注

索引文档

当你向 Elasticsearch 添加文档时,可以索引 JSON 文档。这自然映射到 PHP 的关联数组,因为它们很容易的用 JSON 编码。因此,在 Elasticsearch-PHP 中你可以创建关联数组并将其传给客户端进行索引。有几种方法可以将数据提取到 Elasticsearch 中,这里我们都将会介绍

单文档索引

当你查找文档时,你可以提供一个 ID 或者让 elasticsearch 给你生成一个 ID。

提供 ID 值

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

// Document will be indexed to my_index/my_type/my_id
$response = $client->index($params);

省略 ID 值

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

// Document will be indexed to my_index/my_type/<autogenerated ID>
$response = $client->index($params);

如果你需要设置其他参数,例如 routing 值,你可以在 indextype 等旁边指定数组中的那些参数。例如,我们可以在新的文档中设置路由和时间戳:

附加参数

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

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

批量索引

Elasticsearch 也支持批量索引文档。 批量 API 需要提供 JSON 格式的 action/元数据对,由换行符分割。 当在 PHP 中构建文档也是相似的, 首先创造一个 action 数组对象 (例如 index 对象), 然后你还要创建一个 body 对象。而 PHP 程序则重复上述操作构建文档数据。

一个简单的例子如下所示:

使用 PHP 数组批量索引

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

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

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

实际上在一次 bulk 请求中发送数量会比文档实际数量少。如果是这种情况,您需要对请求进行批处理并定期发送:

批量索引与批次

$params = ['body' => []];

for ($i = 1; $i <= 1234567; $i++) {
    $params['body'][] = [
        'index' => [
            '_index' => 'my_index',
            '_type' => 'my_type',
            '_id' => $i
        ]
    ];

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

    // 每 1000 个文件 停止并批量发送请求
    if ($i % 1000 == 0) {
        $responses = $client->bulk($params);

        // 删除旧的批量请求
        $params = ['body' => []];

        // 为了节约内存,在完成时取消批量响应
        unset($responses);
    }
}

// 如果最后一批存在,那么就发送
if (!empty($params['body'])) {
    $responses = $client->bulk($params);
}

获取文档

Elasticsearch 提供了实时获取文档。这意味着只要文档被编入索引并且在客户端得到确认,您可以从任何分片中检索文档。 通过它的完整 索引/类型/id 路径请求文档来执行获取操作:

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

// 在 /my_index/my_type/my_id 中获取文档
$response = $client->get($params);

更新文档

更新文档允许您完全替换现有的文档,或者仅仅更新某些字段(更改现有字段或者添加新字段)。

部分文档更新

如果要更新部分文档(例如,更改现有字段或者添加新字段)你可以在 body 参数中指定 doc 来实现。这会将 doc 中的字段与现有文档合并。

$params = [
    'index' => 'my_index',
    'type' => 'my_type',
    'id' => 'my_id',
    'body' => [
        'doc' => [
            'new_field' => 'abc'
        ]
    ]
];

// 在 /my_index/my_type/my_id 中更新文档
$response = $client->update($params);

脚本文档更新

有时候您需要执行脚本更新,比如计数器的递增或者在一个数组添加一个新值。为了执行脚本更新,您需要提供一份脚本和(通常)一系列参数:

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

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

Upserts

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

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

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

删除文件

最后,你可以通过指定完整的 /index/type/id 路径来删除文档:

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

// 删除 /my_index/my_type/my_id 目录下的文件
$response = $client->delete($params);

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/elasticsearch-p...

译文地址:https://learnku.com/docs/elasticsearch-p...

上一篇 下一篇
贡献者:5
讨论数量: 0
发起讨论 只看当前版本


暂无话题~