2016-11-29 5 views
3

私たちのプロジェクトの1つでElasticSearchを使用する予定です。現在、ElasticSearch 5.0.1を当社のデータでテストしています。我々は我々が得ている、次のエラーをelasticsearchするために私たちのMySQLテーブルから一括アップロードを行っているときに我々が直面している問題の一つです...PHPによるエラスティックサーチバルクアップロードエラー - インデックスの総フィールド数の上限が1000を超えました

java.lang.IllegalArgumentException: Limit of total fields [1000] in index [shopfront] has been exceeded 
at org.elasticsearch.index.mapper.MapperService.checkTotalFieldsLimit(MapperService.java:482) ~[elasticsearch-5.0.1.jar:5.0.1] 
at org.elasticsearch.index.mapper.MapperService.merge(MapperService.java:343) ~[elasticsearch-5.0.1.jar:5.0.1] 
at org.elasticsearch.index.mapper.MapperService.merge(MapperService.java:277) ~[elasticsearch-5.0.1.jar:5.0.1] 
at org.elasticsearch.cluster.metadata.MetaDataMappingService$PutMappingExecutor.applyRequest(MetaDataMappingService.java:323) ~[elasticsearch-5.0.1.jar:5.0.1] 
at org.elasticsearch.cluster.metadata.MetaDataMappingService$PutMappingExecutor.execute(MetaDataMappingService.java:241) ~[elasticsearch-5.0.1.jar:5.0.1] 
at org.elasticsearch.cluster.service.ClusterService.runTasksForExecutor(ClusterService.java:555) ~[elasticsearch-5.0.1.jar:5.0.1] 
at org.elasticsearch.cluster.service.ClusterService$UpdateTask.run(ClusterService.java:896) ~[elasticsearch-5.0.1.jar:5.0.1] 
at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingRunnable.run(ThreadContext.java:451) ~[elasticsearch-5.0.1.jar:5.0.1] 
at org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.runAndClean(PrioritizedEsThreadPoolExecutor.java:238) ~[elasticsearch-5.0.1.jar:5.0.1] 
at org.elasticsearch.common.util.concurrent.PrioritizedEsThreadPoolExecutor$TieBreakingPrioritizedRunnable.run(PrioritizedEsThreadPoolExecutor.java:201) ~[elasticsearch-5.0.1.jar:5.0.1] 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_111] 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_111] 
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_111] 

我々はelasticsearchクライアントとしてPHPを使用している弾性へのMySQLから一括アップロードを行うことに。いくつかの検索を行った後、私はこの情報を入手しました - https://discuss.elastic.co/t/es-2-3-5-x-metricbeat-index-field-limit/66821

どこかで "index.mapping.total_fields.limit"を使ってそのことを修正すると読んでいます。しかし、私のPHPコードでその使い方を理解することはできません。ここに私のPHPコードです。

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

$i = 1; 
foreach ($productsList as $key => $value) { 

    $params['body'][] = [ 
     'index' => [ 
      '_index' => 'shopfront', 
      '_type' => 'products' 
     ], 
     'settings' => ['index.mapping.total_fields.limit' => 3000] 
    ]; 

    $params['body'][] = [ 
     'product_displayname' => $value['product_displayname'], 
     'product_price' => $value['product_price'], 
     'popularity' => $value['popularity'], 
     'lowestcomp_price' => $value['lowestcomp_price'] 
    ]; 

    // Every 1000 documents stop and send the bulk request 
    if ($i % 1000 == 0) { 
     $responses = $client->bulk($params); 

     // erase the old bulk request 
     $params = ['body' => []]; 

     // unset the bulk response when you are done to save memory 
     unset($responses); 
    } 

    $i++; 
} 

// Send the last batch if it exists 
if (!empty($params['body'])) { 
    $responses = $client->bulk($params); 
} 

NOTE - 私はそれはそれで正常に動作していますElasticsearch 2.4.1 &と同じコードを使用しました。

答えて

15

ESでは、ESの人々は、マッピングの爆発を防ぐためにマッピングタイプに含めることができるフィールドの数を制限することに決めました。あなたが気づいてきたように、その制限は、マッピング1000のフィールドに設定されていますが、あなたはこのように、インデックス作成時またはupdating the index settingsのいずれかによって設定index.mapping.total_fields.limitを指定することで、ニーズに合わせてその制限を解除することができます

curl -XPUT 'localhost:9200/shopfront/_settings' -d ' 
{ 
    "index.mapping.total_fields.limit": 3000 
}' 

あなたはまた、多くのフィールドを持つことが良いことであるかどうかを自問する必要があることに注意してください。それらはすべて必要ですか?いくつかを組み合わせることはできますか?

+0

場合上のコードで '' 'settings '=> [' index.mapping.total_fields.limit '=> 3000]' ''を使ったことが分かります。それは正しいのですか? – mi6crazyheart

+0

いいえ、バルクコールで指定することはできません。インデックス作成時に行う必要があります。または、これまで説明したようにインデックス設定を更新するだけです。それは一回限りのコールなので、あなたはそのカールを実行することができ、あなたは大丈夫です。 – Val

+0

私はこの '' curl -XPUT 'localhost:9200/shopfront?pretty' -d '{"settings":{"index":{"number_of_shards":3、 "number_of_replicas":2}、 "index.mapping"を行いました。 total_fields.limit ":50000}} '' ''&それは働いた。私を助けてくれてありがとう。 1つの疑問 - 私はJSONのドキュメントに4フィールドしか送っていないので、2000/3000の制限をどのように計算して計算するのか? – mi6crazyheart

1

この機能はこのgithub issueで決定されました。この問題を解決するための二つの方法:インデックスを作成するときに

あなたはより大きな値を指定することができます。

PUT test 
{ 
    "shopfront": { 
    "index.mapping.total_fields.limit": 2000, 
    "number_of_shards": 5, 
    "number_of_replicas": 2 
    }, 
    "mappings": { 
    ... 
    } 
} 

それとも、既存のインデックスの上限を増やすしたい場合は:

PUT shopfront/_settings 
{ 
    "index.mapping.total_fields.limit": 2000 
} 
関連する問題