Elasticsearch PHP добавляет маршрутизацию в дочерний документ

#php #elasticsearch #routes #parent-child

#php #elasticsearch #маршруты #родитель-потомок

Вопрос:

Сервер базы данных: Elasticsearch 7.9.2 Centos 7.7

Dev env: PHP 7.3.11 macOS

Я довольно новичок в Elasticsearch, поэтому, пожалуйста, поделитесь со мной этим. Однако это сводит меня с ума.

Я пытаюсь сделать что-то очень простое, но, поскольку я из мира реляционных баз данных, мне нужно немного разума. Я создал сопоставление с отношением родитель-потомок.

 Product --> Price
  

Это созданное мной сопоставление:

 PUT /products_pc
{
 "mappings": { 
    "properties": {
      "datafeed_id": {
        "type": "integer"
      },
      "date_add": {
        "type": "date"
      },
      "description": {
        "type": "text"
      },
      "ean": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "image_url": {
        "type": "text",
        "index": false
      },
      "name": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "sku": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
        "webshop_id": {
        "type": "integer"
      },
      "price": {
        "type": "float"
      },
      "url": {
        "type": "text"
      },
        "date_mod":{
          "type": "date"
        },
        "product_price" : {
          "type":"join",
          "relations": {
            "product":"price"
          }
        }
    }
  }
}
  

Пока все хорошо. Когда я вручную добавляю продукт и 2 цены, я могу получить то, что и ожидал: 1 родительский документ с 2 дочерними документами.

Теперь на PHP я могу индексировать родительский документ, но не для дочерних документов. Похоже, я не могу отправить параметр маршрутизации (который я могу с помощью Kibana)

Это то, что я пробовал в PHP, parent _id = 123

 $hosts = ['xxx.xxx.xxx.xxx:9200'];
$client = ClientBuilder::create()
    ->setHosts($hosts)
    ->build();    

$params['body'][] = [
    'create' => [
        '_index' => 'products_pc',
        '_id' => '123_1'
    ]
];
$params['body'][] = [
    'webshop_id' => 1,
    'date_mod' => time(),
    'price' => 12,
    'url' => '',
    'product_price' => [
        'name' => 'price',
        'parent' => 123
    ]
];
$client->bulk($params);
  

Но это не работает, так как нет набора маршрутизации. Если я добавлю ‘_routing’ => 123 ниже поля _id, я получаю сообщение об ошибке 400, сообщающее мне, что поле _routing неверно («Строка действия / метаданных [3] содержит неизвестный параметр [_routing]»)

Я искал уже 2 дня, бегая по кругу. Все разные версии Elasticsearch немного отличаются, поэтому я должен признать, что я потерялся. Есть ли кто-нибудь, кто может указать мне на мою ошибку? Или подсказка в правильном направлении? Это сводит меня с ума. (Поскольку я боюсь, что это будет слишком просто сделать …)

Заранее спасибо!

Ответ №1:

Итак, мы здесь, после еще 2 дней поиска… Но, похоже, я нашел решение…

После еще нескольких часов поиска я оказался на этой странице (снова): https://elastic.co/guide/en/elasticsearch/client/php-api/current/ElasticsearchPHP_Endpoints.html#Elasticsearch_Clientbulk_bulk

И вот оно, в списке параметров массовой конечной точки:

 $params['routing']                =  // (string) Specific routing value
  

Сначала не совсем уверен, как это использовать, но…
Затем я попробовал это для каждого из дочерних документов, что, похоже, делает свое дело!

 $hosts = ['xxx.xxx.xxx.xxx:9200'];
$client = ClientBuilder::create()
    ->setHosts($hosts)
    ->build();

// insert price
$params['body'][] = [
    'index' => [
        '_index' => 'products_pc',
        '_id' => '123_1',
        'routing' => 123 // <-- Insert routing here.
    ]
];
$params['body'][] = [
    'webshop_id' => 1,
    'date_mod' => time(),
    'price' => 12,
    'url' => '',
    'product_price' => [
        'name' => 'price',
        'parent' => 123 // <-- Parent _id value
    ]
];

$client->bulk($params);
  

Как и предполагалось ранее, на самом деле слишком просто. Но я думаю, что это жизнь программиста.

Однако имейте в виду, что во МНОГИХ документах упоминается поле _routing (даже в официальных документах для версии 7.9: https://www.elastic.co/guide/en/elasticsearch/reference/7.9/mapping-routing-field.html Как видно из текста, как в правом подменю в разделе поля метаданных), но на самом деле это поле просто «маршрутизация». Может сэкономить вам пару дней 😉