添付プロセッサ
添付プロセッサは、Apacheテキスト抽出ライブラリTikaを使用して、Elasticsearchが一般的な形式(PPT、XLS、PDFなど)のファイル添付を抽出できるようにします。
ソースフィールドはbase64エンコードされたバイナリである必要があります。 base64間の変換のオーバーヘッドを避けたい場合は、JSONの代わりにCBOR形式を使用し、フィールドを文字列表現ではなくバイト配列として指定できます。プロセッサはその場合、base64デコードをスキップします。
パイプラインでの添付プロセッサの使用
名前 | 必須 | デフォルト | 説明 |
---|---|---|---|
field |
はい | - | base64エンコードされたフィールドを取得するフィールド |
target_field |
いいえ | attachment | 添付情報を保持するフィールド |
indexed_chars |
いいえ | 100000 | 巨大なフィールドを防ぐために抽出に使用される文字数。制限なしの場合は-1 を使用します。 |
indexed_chars_field |
いいえ | null |
抽出に使用される文字数を上書きできるフィールド名。indexed_chars を参照してください。 |
properties |
いいえ | すべてのプロパティ | 保存するプロパティの配列。content 、title 、name 、author 、keywords 、date 、content_type 、content_length 、language が含まれます。 |
ignore_missing |
いいえ | false |
true およびfield が存在しない場合、プロセッサはドキュメントを変更せずに静かに終了します。 |
remove_binary |
いいえ | false |
true の場合、バイナリfield はドキュメントから削除されます。 |
resource_name |
いいえ | デコードするリソースの名前を含むフィールド。指定された場合、プロセッサはこのリソース名を基盤となるTikaライブラリに渡してリソース名ベースの検出を有効にします。 |
例
JSONドキュメントにファイルを添付する場合、最初にファイルをbase64文字列としてエンコードする必要があります。Unix系システムでは、base64
コマンドを使用してこれを行うことができます:
シェル
base64 -in myfile.rtf
コマンドはファイルのbase64エンコードされた文字列を返します。次のbase64文字列は、テキストLorem ipsum dolor sit amet
を含む.rtf
ファイルのものです: e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=
。
添付プロセッサを使用して文字列をデコードし、ファイルのプロパティを抽出します:
Python
resp = client.ingest.put_pipeline(
id="attachment",
description="Extract attachment information",
processors=[
{
"attachment": {
"field": "data",
"remove_binary": False
}
}
],
)
print(resp)
resp1 = client.index(
index="my-index-000001",
id="my_id",
pipeline="attachment",
document={
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0="
},
)
print(resp1)
resp2 = client.get(
index="my-index-000001",
id="my_id",
)
print(resp2)
Ruby
response = client.ingest.put_pipeline(
id: 'attachment',
body: {
description: 'Extract attachment information',
processors: [
{
attachment: {
field: 'data',
remove_binary: false
}
}
]
}
)
puts response
response = client.index(
index: 'my-index-000001',
id: 'my_id',
pipeline: 'attachment',
body: {
data: 'e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0='
}
)
puts response
response = client.get(
index: 'my-index-000001',
id: 'my_id'
)
puts response
Js
const response = await client.ingest.putPipeline({
id: "attachment",
description: "Extract attachment information",
processors: [
{
attachment: {
field: "data",
remove_binary: false,
},
},
],
});
console.log(response);
const response1 = await client.index({
index: "my-index-000001",
id: "my_id",
pipeline: "attachment",
document: {
data: "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
},
});
console.log(response1);
const response2 = await client.get({
index: "my-index-000001",
id: "my_id",
});
console.log(response2);
コンソール
PUT _ingest/pipeline/attachment
{
"description" : "Extract attachment information",
"processors" : [
{
"attachment" : {
"field" : "data",
"remove_binary": false
}
}
]
}
PUT my-index-000001/_doc/my_id?pipeline=attachment
{
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0="
}
GET my-index-000001/_doc/my_id
ドキュメントのattachment
オブジェクトには、ファイルの抽出されたプロパティが含まれています:
コンソール-結果
{
"found": true,
"_index": "my-index-000001",
"_id": "my_id",
"_version": 1,
"_seq_no": 22,
"_primary_term": 1,
"_source": {
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
"attachment": {
"content_type": "application/rtf",
"language": "ro",
"content": "Lorem ipsum dolor sit amet",
"content_length": 28
}
}
}
ドキュメント内にバイナリをフィールドとして保持することは、多くのリソースを消費する可能性があります。このフィールドをドキュメントから削除することを強くお勧めします。remove_binary
をtrue
に設定して、フィールドを自動的に削除します。
エクスポートされたフィールド
ドキュメントから抽出される可能性のあるフィールドは次のとおりです:
content
,title
,author
,keywords
,date
,content_type
,content_length
,language
,modified
,format
,identifier
,contributor
,coverage
,modifier
,creator_tool
,publisher
,relation
,rights
,source
,type
,description
,print_date
,metadata_date
,latitude
,longitude
,altitude
,rating
,comments
特定のattachment
フィールドのみを抽出するには、properties
配列を指定します:
Python
resp = client.ingest.put_pipeline(
id="attachment",
description="Extract attachment information",
processors=[
{
"attachment": {
"field": "data",
"properties": [
"content",
"title"
],
"remove_binary": False
}
}
],
)
print(resp)
Ruby
response = client.ingest.put_pipeline(
id: 'attachment',
body: {
description: 'Extract attachment information',
processors: [
{
attachment: {
field: 'data',
properties: [
'content',
'title'
],
remove_binary: false
}
}
]
}
)
puts response
Js
const response = await client.ingest.putPipeline({
id: "attachment",
description: "Extract attachment information",
processors: [
{
attachment: {
field: "data",
properties: ["content", "title"],
remove_binary: false,
},
},
],
});
console.log(response);
コンソール
PUT _ingest/pipeline/attachment
{
"description" : "Extract attachment information",
"processors" : [
{
"attachment" : {
"field" : "data",
"properties": [ "content", "title" ],
"remove_binary": false
}
}
]
}
バイナリデータからコンテンツを抽出することはリソース集約的な操作であり、多くのリソースを消費します。このプロセッサを使用してパイプラインを実行するには、専用のインジェストノードを使用することを強くお勧めします。
CBORで添付プロセッサを使用する
JSONをbase64にエンコードおよびデコードするのを避けるために、代わりにCBORデータを添付プロセッサに渡すことができます。たとえば、次のリクエストは、添付プロセッサを使用するcbor-attachment
パイプラインを作成します。
Python
resp = client.ingest.put_pipeline(
id="cbor-attachment",
description="Extract attachment information",
processors=[
{
"attachment": {
"field": "data",
"remove_binary": False
}
}
],
)
print(resp)
Ruby
response = client.ingest.put_pipeline(
id: 'cbor-attachment',
body: {
description: 'Extract attachment information',
processors: [
{
attachment: {
field: 'data',
remove_binary: false
}
}
]
}
)
puts response
Js
const response = await client.ingest.putPipeline({
id: "cbor-attachment",
description: "Extract attachment information",
processors: [
{
attachment: {
field: "data",
remove_binary: false,
},
},
],
});
console.log(response);
コンソール
PUT _ingest/pipeline/cbor-attachment
{
"description" : "Extract attachment information",
"processors" : [
{
"attachment" : {
"field" : "data",
"remove_binary": false
}
}
]
}
次のPythonスクリプトは、cbor-attachment
パイプラインを含むHTTPインデックスリクエストにCBORデータを渡します。HTTPリクエストヘッダーは、content-type
のapplication/cbor
を使用します。
すべてのElasticsearchクライアントがカスタムHTTPリクエストヘッダーをサポートしているわけではありません。
Python
import cbor2
import requests
file = 'my-file'
headers = {'content-type': 'application/cbor'}
with open(file, 'rb') as f:
doc = {
'data': f.read()
}
requests.put(
'http://localhost:9200/my-index-000001/_doc/my_id?pipeline=cbor-attachment',
data=cbor2.dumps(doc),
headers=headers
)
抽出される文字数の制限
あまりにも多くの文字を抽出してノードメモリをオーバーロードしないように、抽出に使用される文字数はデフォルトで100000
に制限されています。この値はindexed_chars
を設定することで変更できます。制限なしの場合は-1
を使用しますが、これを設定する際には、ノードが非常に大きなドキュメントの内容を抽出するのに十分なHEAPを持っていることを確認してください。
特定のフィールドから抽出して設定する制限を定義することもできます。ドキュメントにそのフィールドがある場合、indexed_chars
設定が上書きされます。このフィールドを設定するには、indexed_chars_field
設定を定義します。
たとえば:
Python
resp = client.ingest.put_pipeline(
id="attachment",
description="Extract attachment information",
processors=[
{
"attachment": {
"field": "data",
"indexed_chars": 11,
"indexed_chars_field": "max_size",
"remove_binary": False
}
}
],
)
print(resp)
resp1 = client.index(
index="my-index-000001",
id="my_id",
pipeline="attachment",
document={
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0="
},
)
print(resp1)
resp2 = client.get(
index="my-index-000001",
id="my_id",
)
print(resp2)
Ruby
response = client.ingest.put_pipeline(
id: 'attachment',
body: {
description: 'Extract attachment information',
processors: [
{
attachment: {
field: 'data',
indexed_chars: 11,
indexed_chars_field: 'max_size',
remove_binary: false
}
}
]
}
)
puts response
response = client.index(
index: 'my-index-000001',
id: 'my_id',
pipeline: 'attachment',
body: {
data: 'e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0='
}
)
puts response
response = client.get(
index: 'my-index-000001',
id: 'my_id'
)
puts response
Js
const response = await client.ingest.putPipeline({
id: "attachment",
description: "Extract attachment information",
processors: [
{
attachment: {
field: "data",
indexed_chars: 11,
indexed_chars_field: "max_size",
remove_binary: false,
},
},
],
});
console.log(response);
const response1 = await client.index({
index: "my-index-000001",
id: "my_id",
pipeline: "attachment",
document: {
data: "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
},
});
console.log(response1);
const response2 = await client.get({
index: "my-index-000001",
id: "my_id",
});
console.log(response2);
コンソール
PUT _ingest/pipeline/attachment
{
"description" : "Extract attachment information",
"processors" : [
{
"attachment" : {
"field" : "data",
"indexed_chars" : 11,
"indexed_chars_field" : "max_size",
"remove_binary": false
}
}
]
}
PUT my-index-000001/_doc/my_id?pipeline=attachment
{
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0="
}
GET my-index-000001/_doc/my_id
コンソール-結果
{
"found": true,
"_index": "my-index-000001",
"_id": "my_id",
"_version": 1,
"_seq_no": 35,
"_primary_term": 1,
"_source": {
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
"attachment": {
"content_type": "application/rtf",
"language": "is",
"content": "Lorem ipsum",
"content_length": 11
}
}
}
Python
resp = client.ingest.put_pipeline(
id="attachment",
description="Extract attachment information",
processors=[
{
"attachment": {
"field": "data",
"indexed_chars": 11,
"indexed_chars_field": "max_size",
"remove_binary": False
}
}
],
)
print(resp)
resp1 = client.index(
index="my-index-000001",
id="my_id_2",
pipeline="attachment",
document={
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
"max_size": 5
},
)
print(resp1)
resp2 = client.get(
index="my-index-000001",
id="my_id_2",
)
print(resp2)
Ruby
response = client.ingest.put_pipeline(
id: 'attachment',
body: {
description: 'Extract attachment information',
processors: [
{
attachment: {
field: 'data',
indexed_chars: 11,
indexed_chars_field: 'max_size',
remove_binary: false
}
}
]
}
)
puts response
response = client.index(
index: 'my-index-000001',
id: 'my_id_2',
pipeline: 'attachment',
body: {
data: 'e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=',
max_size: 5
}
)
puts response
response = client.get(
index: 'my-index-000001',
id: 'my_id_2'
)
puts response
Js
const response = await client.ingest.putPipeline({
id: "attachment",
description: "Extract attachment information",
processors: [
{
attachment: {
field: "data",
indexed_chars: 11,
indexed_chars_field: "max_size",
remove_binary: false,
},
},
],
});
console.log(response);
const response1 = await client.index({
index: "my-index-000001",
id: "my_id_2",
pipeline: "attachment",
document: {
data: "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
max_size: 5,
},
});
console.log(response1);
const response2 = await client.get({
index: "my-index-000001",
id: "my_id_2",
});
console.log(response2);
コンソール
PUT _ingest/pipeline/attachment
{
"description" : "Extract attachment information",
"processors" : [
{
"attachment" : {
"field" : "data",
"indexed_chars" : 11,
"indexed_chars_field" : "max_size",
"remove_binary": false
}
}
]
}
PUT my-index-000001/_doc/my_id_2?pipeline=attachment
{
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
"max_size": 5
}
GET my-index-000001/_doc/my_id_2
コンソール-結果
{
"found": true,
"_index": "my-index-000001",
"_id": "my_id_2",
"_version": 1,
"_seq_no": 40,
"_primary_term": 1,
"_source": {
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
"max_size": 5,
"attachment": {
"content_type": "application/rtf",
"language": "sl",
"content": "Lorem",
"content_length": 5
}
}
}
配列での添付プロセッサの使用
添付プロセッサを添付の配列内で使用するには、foreachプロセッサが必要です。これにより、添付プロセッサが配列の各要素で実行されるようになります。
たとえば、次のソースがあるとします:
Js
{
"attachments" : [
{
"filename" : "ipsum.txt",
"data" : "dGhpcyBpcwpqdXN0IHNvbWUgdGV4dAo="
},
{
"filename" : "test.txt",
"data" : "VGhpcyBpcyBhIHRlc3QK"
}
]
}
この場合、添付フィールドの各要素のデータフィールドを処理し、プロパティをドキュメントに挿入したいので、次のforeach
プロセッサが使用されます:
Python
resp = client.ingest.put_pipeline(
id="attachment",
description="Extract attachment information from arrays",
processors=[
{
"foreach": {
"field": "attachments",
"processor": {
"attachment": {
"target_field": "_ingest._value.attachment",
"field": "_ingest._value.data",
"remove_binary": False
}
}
}
}
],
)
print(resp)
resp1 = client.index(
index="my-index-000001",
id="my_id",
pipeline="attachment",
document={
"attachments": [
{
"filename": "ipsum.txt",
"data": "dGhpcyBpcwpqdXN0IHNvbWUgdGV4dAo="
},
{
"filename": "test.txt",
"data": "VGhpcyBpcyBhIHRlc3QK"
}
]
},
)
print(resp1)
resp2 = client.get(
index="my-index-000001",
id="my_id",
)
print(resp2)
Ruby
response = client.ingest.put_pipeline(
id: 'attachment',
body: {
description: 'Extract attachment information from arrays',
processors: [
{
foreach: {
field: 'attachments',
processor: {
attachment: {
target_field: '_ingest._value.attachment',
field: '_ingest._value.data',
remove_binary: false
}
}
}
}
]
}
)
puts response
response = client.index(
index: 'my-index-000001',
id: 'my_id',
pipeline: 'attachment',
body: {
attachments: [
{
filename: 'ipsum.txt',
data: 'dGhpcyBpcwpqdXN0IHNvbWUgdGV4dAo='
},
{
filename: 'test.txt',
data: 'VGhpcyBpcyBhIHRlc3QK'
}
]
}
)
puts response
response = client.get(
index: 'my-index-000001',
id: 'my_id'
)
puts response
Js
const response = await client.ingest.putPipeline({
id: "attachment",
description: "Extract attachment information from arrays",
processors: [
{
foreach: {
field: "attachments",
processor: {
attachment: {
target_field: "_ingest._value.attachment",
field: "_ingest._value.data",
remove_binary: false,
},
},
},
},
],
});
console.log(response);
const response1 = await client.index({
index: "my-index-000001",
id: "my_id",
pipeline: "attachment",
document: {
attachments: [
{
filename: "ipsum.txt",
data: "dGhpcyBpcwpqdXN0IHNvbWUgdGV4dAo=",
},
{
filename: "test.txt",
data: "VGhpcyBpcyBhIHRlc3QK",
},
],
},
});
console.log(response1);
const response2 = await client.get({
index: "my-index-000001",
id: "my_id",
});
console.log(response2);
コンソール
PUT _ingest/pipeline/attachment
{
"description" : "Extract attachment information from arrays",
"processors" : [
{
"foreach": {
"field": "attachments",
"processor": {
"attachment": {
"target_field": "_ingest._value.attachment",
"field": "_ingest._value.data",
"remove_binary": false
}
}
}
}
]
}
PUT my-index-000001/_doc/my_id?pipeline=attachment
{
"attachments" : [
{
"filename" : "ipsum.txt",
"data" : "dGhpcyBpcwpqdXN0IHNvbWUgdGV4dAo="
},
{
"filename" : "test.txt",
"data" : "VGhpcyBpcyBhIHRlc3QK"
}
]
}
GET my-index-000001/_doc/my_id
コンソール-結果
{
"_index" : "my-index-000001",
"_id" : "my_id",
"_version" : 1,
"_seq_no" : 50,
"_primary_term" : 1,
"found" : true,
"_source" : {
"attachments" : [
{
"filename" : "ipsum.txt",
"data" : "dGhpcyBpcwpqdXN0IHNvbWUgdGV4dAo=",
"attachment" : {
"content_type" : "text/plain; charset=ISO-8859-1",
"language" : "en",
"content" : "this is\njust some text",
"content_length" : 24
}
},
{
"filename" : "test.txt",
"data" : "VGhpcyBpcyBhIHRlc3QK",
"attachment" : {
"content_type" : "text/plain; charset=ISO-8859-1",
"language" : "en",
"content" : "This is a test",
"content_length" : 16
}
}
]
}
}
target_field
を設定する必要があることに注意してください。そうしないと、デフォルト値が使用され、トップレベルフィールドattachment
が使用されます。このトップレベルフィールドのプロパティには、最初の添付ファイルの値のみが含まれます。ただし、target_field
を_ingest._value
の値に指定することで、プロパティが正しい添付ファイルに正しく関連付けられます。