Я читаю руководство об индексации документов в Elasticsearch.
Есть пример с массовой индексацией. У меня есть вопрос, это правильно, когда создается массив с двумя ключами для одного элемента в цикле:
for($i = 0; $i < 100; $i++) {
$params['body'][] = array(
'index' => array(
'_id' => $i
)
);
$params['body'][] = array(
'my_field' => 'my_value',
'second_field' => 'some more values'
);
}
Почему есть две инициализации массива $params['body'][]
в цикле?
Должна быть установка индекса по тому же ключу, как и my_field
?
Я имею в виду один случай, когда вся информация об индексе добавляется в массив одним ключом (индексом):
$params['body'][] = array(
'index' => array(
'_id' => $i
),
'my_field' => 'my_value',
'second_field' => 'some more values'
);
Также после поискового запроса я получаю ошибку:
Сообщение: недопустимое смещение строки ‘match’ в строке, где:
$query['match']['name'] = $query;
где $query
это строка
Я полагаю, что это ошибка с проблемой в создании индекса, поэтому я начал с этого.
Мой код, который добавляет документ в индекс:
private function addDocument($data = array(), $type)
{
if (!empty($data)) {
foreach ($data as $key => $val) {
$params['body'][] = array(
'index' => array(
'_id' => $key,
'_type' => 'profiles',
'_index' => $this->_typeIndex($type)
)
);
$params['body'][] = (array)$val;
}
$this->client->bulk($params);
}
}
Это правильно? Потому что в поиске я получаю ошибку, описанную здесь
Чтобы массовое индексирование работало, полезная нагрузка должна содержать одну строку команды (индекс, тип, идентификатор документа) и одну строку содержимого (фактические поля документа) для каждого документа, например:
{"index": {"_id": "1234"}} <--- command for doc1
{"field1": "value1", "field2": "value2"} <--- source for doc1
{"index": {"_id": "1234"}} <--- command for doc2
{"field1": "value1", "field2": "value2"} <--- source for doc2
...
Пример PHP, который вы привели, делает именно это:
$params['body'][] = array(
'index' => array(
'_id' => $i
)
);
создаст первое чтение командной строки {"index": {"_id": "0"}}
а также
$params['body'][] = array(
'my_field' => 'my_value',
'second_field' => 'some more values'
);
создаст вторую строку содержимого для чтения {"my_field": "my_value", "second_field": "some more values"}
Цикл for делает это 100x и создает полезную нагрузку, содержащую 200 строк для 100 документов.
Если вы соедините тело, как вы сделали с
$params['body'][] = array(
'index' => array(
'_id' => $i
),
'my_field' => 'my_value',
'second_field' => 'some more values'
);
Это не будет работать, потому что при каждом чтении документа будет получаться одна строка:
{"index":{"_id": "0"}, "my_field": "my_value", "second_field": "some more values"}
И массовая операция не удастся …
Попробуйте снова.
ОБНОВИТЬ
Это не работает, потому что вы добавляете слишком много строк. Вы должны удалить foreach
и просто сделай это так. Я просто не знаю, как твои id
поле называется. Также я полагаю, $data
массив содержит поля документа для добавления.
private function addDocument($data = array(), $type)
{
if (!empty($data)) {
$params['body'][] = array(
'index' => array(
'_id' => $data['id'], <--- make sure to use the right id field
'_type' => 'profiles',
'_index' => $this->_typeIndex($type)
)
);
$params['body'][] = $data;
$this->client->bulk($params);
}
}
Других решений пока нет …