Elasticsearch data sources provide bidirectional read and write channels for synchronizing data between DataWorks and Elasticsearch.
Applicability
Public resource groups support Elasticsearch 5.x, while Serverless resource groups (recommended) and dedicated resource groups for data integration support Elasticsearch 5.x, 6.x, 7.x, and 8.x.
-
For details on Serverless resource groups, see Use a Serverless resource group.
-
For details on dedicated resource groups for data integration, see Use a dedicated resource group for data integration.
Elasticsearch is an open-source, enterprise-grade search engine developed under the Apache license. Built on Lucene, it provides distributed search and data analysis capabilities. The following table maps core Elasticsearch concepts to their relational database counterparts.
|
Elasticsearch |
Relational database |
|
Elasticsearch (instance) |
relational database (instance) |
|
index |
database |
|
type |
table |
|
document |
row |
|
field |
column |
An Elasticsearch instance can contain multiple indexes. Each index holds multiple types, each type contains multiple documents, and each document consists of multiple fields. The Elasticsearch Writer plugin uses the Elasticsearch REST API to batch write data to Elasticsearch.
Supported versions
DataWorks supports Alibaba Cloud Elasticsearch versions 5.x, 6.x, 7.x, and 8.x, but not self-managed Elasticsearch.
Limitations
The following limitations apply to offline reads from and writes to Elasticsearch:
-
The Elasticsearch Reader fetches shard information from the server for data synchronization. All shards must be active during synchronization to prevent data inconsistency.
-
For Elasticsearch 6.x or later, you can use a serverless resource group (recommended) or an exclusive resource group for Data Integration.
-
scaled_floatfields cannot be synchronized. -
Indexes cannot be synchronized if their field names contain the keyword
$ref.
Supported field types
|
Type |
Offline read |
Offline write |
Real-time write |
|
binary |
Supported |
Supported |
Supported |
|
boolean |
Supported |
Supported |
Supported |
|
keyword |
Supported |
Supported |
Supported |
|
constant_keyword |
Not supported |
Not supported |
Not supported |
|
wildcard |
Not supported |
Not supported |
Not supported |
|
long |
Supported |
Supported |
Supported |
|
integer |
Supported |
Supported |
Supported |
|
short |
Supported |
Supported |
Supported |
|
byte |
Supported |
Supported |
Supported |
|
double |
Supported |
Supported |
Supported |
|
float |
Supported |
Supported |
Supported |
|
half_float |
Not supported |
Not supported |
Not supported |
|
scaled_float |
Not supported |
Not supported |
Not supported |
|
unsigned_long |
Not supported |
Not supported |
Not supported |
|
date |
Supported |
Supported |
Supported |
|
date_nanos |
Not supported |
Not supported |
Not supported |
|
alias |
Not supported |
Not supported |
Not supported |
|
object |
Supported |
Supported |
Supported |
|
flattened |
Not supported |
Not supported |
Not supported |
|
nested |
Supported |
Supported |
Supported |
|
join |
Not supported |
Not supported |
Not supported |
|
integer_range |
Supported |
Supported |
Supported |
|
float_range |
Supported |
Supported |
Supported |
|
long_range |
Supported |
Supported |
Supported |
|
double_range |
Supported |
Supported |
Supported |
|
date_range |
Supported |
Supported |
Supported |
|
ip_range |
Not supported |
Supported |
Supported |
|
ip |
Supported |
Supported |
Supported |
|
version |
Supported |
Supported |
Supported |
|
murmur3 |
Not supported |
Not supported |
Not supported |
|
aggregate_metric_double |
Not supported |
Not supported |
Not supported |
|
histogram |
Not supported |
Not supported |
Not supported |
|
text |
Supported |
Supported |
Supported |
|
annotated-text |
Not supported |
Not supported |
Not supported |
|
completion |
Supported |
Not supported |
Not supported |
|
search_as_you_type |
Not supported |
Not supported |
Not supported |
|
token_count |
Supported |
Not supported |
Not supported |
|
dense_vector |
Not supported |
Not supported |
Not supported |
|
rank_feature |
Not supported |
Not supported |
Not supported |
|
rank_features |
Not supported |
Not supported |
Not supported |
|
geo_point |
Supported |
Supported |
Supported |
|
geo_shape |
Supported |
Supported |
Supported |
|
point |
Not supported |
Not supported |
Not supported |
|
shape |
Not supported |
Not supported |
Not supported |
|
percolator |
Not supported |
Not supported |
Not supported |
|
string |
Supported |
Supported |
Supported |
How it works
The Elasticsearch Reader works as follows:
-
It uses the Elasticsearch _searchscrollslice API, combining its scroll slice feature with the multi-threaded sharding of Data Integration.
-
It converts data types based on the mapping configuration in Elasticsearch.
For more information, see the official Elasticsearch documentation.
The Elasticsearch Reader fetches shard information from the server for data synchronization. To prevent data inconsistency, you must ensure that all server-side shards remain active during data synchronization.
Basic configuration
In production, remove comments from the code before running the job.
{
"order":{
"hops":[
{
"from":"Reader",
"to":"Writer"
}
]
},
"setting":{
"errorLimit":{
"record":"0" // The error limit. The job stops if the error count exceeds this value.
},
"jvmOption":"",
"speed":{
"concurrent":3, // The number of concurrent threads.
"throttle":true,
"mbps":"12" // The maximum speed in MB/s.
}
},
"steps":[
{
"category":"reader",
"name":"Reader",
"parameter":{
"column":[ // The columns to read.
"id",
"name"
],
"endpoint":"", // The service endpoint.
"index":"", // The source index.
"password":"", // The password for authentication.
"scroll":"", // The scroll context duration.
"search":"", // The query body, same as the `query` object in an Elasticsearch `_search` request.
"type":"default",
"username":"" // The username for authentication.
},
"stepType":"elasticsearch"
},
{
"stepType": "elasticsearch",
"parameter": {
"column": [ // The columns to write.
{
"name": "id",
"type": "integer"
},
{
"name": "name",
"type": "text"
}
],
"index": "test", // The destination index.
"indexType": "", // The index type. Leave this empty for Elasticsearch v7.x or later.
"actionType": "index", // The write mode.
"cleanup": false, // Specifies whether to recreate the index before writing.
"datasource": "test", // The data source name.
"primaryKeyInfo": { // The primary key configuration.
"fieldDelimiterOrigin": ",",
"column": [
"id"
],
"type": "specific",
"fieldDelimiter": ","
},
"dynamic": false, // Specifies whether to enable dynamic mapping.
"batchSize": 1024 // The number of documents to write per batch.
},
"name": "Writer",
"category": "writer"
}
],
"type":"job",
"version":"2.0" // The version number.
}
Advanced features
-
Full document pull
You can pull the entire content of an Elasticsearch document into a single field. For configuration details, see Scenario 1: Full document pull.
-
Transform semi-structured data to structured data
Category
Description
References
Background
Elasticsearch data often has dynamic fields and deep nesting. This feature transforms semi-structured data into structured data for downstream computation and storage.
—
How it works
The solution parses JSON data from Elasticsearch, uses path expressions to flatten nested structures, and maps the results to structured tables. Complex documents can be split into multiple tables as needed.
—
Solutions
For nested JSON data, use a path to access specific properties.
-
property
-
property.sub-property
-
property[0].sub-property
For one-to-many relationships, unroll an array property to split its elements into multiple rows.
property[*].sub-property
Merge and deduplicate elements from a string array into a single property.
property[]
Combine multiple properties into a single property.
property1,property2
Select the first non-null property from a list.
property1|property2
-
Add a data source
Before you develop a synchronization task in DataWorks, you must add the required data source to DataWorks by following the instructions in Data source management. You can view parameter descriptions in the DataWorks console to understand the meanings of the parameters when you add a data source.
Data synchronization tasks
For information about the entry point for and the procedure of configuring a synchronization task, see the following configuration guides.
Offline synchronization task (single table)
-
See Configure a task in the codeless UI or Configure a task in the code editor.
-
For a full parameter reference and a script demo, see Appendix 1: Script demo and parameter descriptions.
Real-time write task (single table)
See Configure a real-time synchronization task in DataStudio (Legacy).
Full-database real-time synchronization
See Configure a real-time full-database synchronization task.
Appendix 1: Script demo and parameters
Configure a batch synchronization task by using the code editor
If you want to configure a batch synchronization task by using the code editor, you must configure the related parameters in the script based on the unified script format requirements. For more information, see Script mode configuration. The following information describes the parameters that you must configure for data sources when you configure a batch synchronization task by using the code editor.
Reader script demo
{
"order":{
"hops":[
{
"from":"Reader",
"to":"Writer"
}
]
},
"setting":{
"errorLimit":{
"record":"0" // The number of error records allowed.
},
"jvmOption":"",
"speed":{
"concurrent":3,
"throttle":false
}
},
"steps":[
{
"category":"reader",
"name":"Reader",
"parameter":{
"column":[ // The columns to read.
"id",
"name"
],
"endpoint":"http://es-cn-xxx.elasticsearch.aliyuncs.com:9200", // The endpoint.
"index":"aliyun_es_xx", // The index.
"password":"*******", // The password.
"multiThread":true,
"scroll":"5m", // The scroll context duration.
"pageSize":5000,
"connTimeOut":600000,
"readTimeOut":600000,
"retryCount":30,
"retrySleepTime":"10000",
"search":{
"range":{
"gmt_modified":{
"gte":0
}
}
}, // Query parameter. The content is identical to the query body of the Elasticsearch _search API.
"type":"doc",
"username":"aliyun_di" // The username.
},
"stepType":"elasticsearch"
},
{
"category":"writer",
"name":"Writer",
"parameter":{ },
"stepType":"stream"
}
],
"type":"job",
"version":"2.0" // The version number.
}
Reader script parameters
|
Parameter |
Description |
Required |
Default |
|
datasource |
The name of an existing DataWorks data source. |
Yes |
None |
|
index |
The name of the index in Elasticsearch. |
Yes |
None |
|
type |
The type name of an index in Elasticsearch. |
No |
Index name |
|
search |
The query body for Elasticsearch. |
Yes |
None |
|
pageSize |
The number of records to read per page. |
No |
100 |
|
scroll |
Specifies how long to keep the Elasticsearch scroll context alive for pagination.
|
Yes |
None |
|
strictMode |
Specifies whether to enable strict mode. If set to |
No |
true |
|
sort |
The field by which to sort the results. |
No |
None |
|
retryCount |
The number of times to retry a failed operation. |
No |
30 |
|
connTimeOut |
The client connection timeout, in milliseconds. |
No |
600,000 |
|
readTimeOut |
The client read timeout, in milliseconds. |
No |
600,000 |
|
multiThread |
Specifies whether to use multiple threads for HTTP requests. |
No |
true |
|
preemptiveAuth |
Specifies whether to use preemptive authentication for HTTP requests. |
No |
false |
|
retrySleepTime |
The interval between retries, in milliseconds. |
No |
10,000 |
|
discovery |
Specifies whether to enable node discovery.
|
No |
false |
|
compression |
Specifies whether to use GZIP to compress the request body. If you use GZIP, you must enable the http.compression setting on the Elasticsearch node. |
No |
false |
|
dateFormat |
If a field to be synchronized is of the date type and the field mapping does not specify a format, you must configure the dateFormat parameter. This configuration must include all formats of the date type fields to be synchronized. Example: |
No |
None |
|
full |
Specifies whether to synchronize the entire document content as a single field to the destination. For more information, see Scenario 1: Full data pull. |
No |
None |
|
multi |
An advanced feature with five use cases. It has two sub-properties: |
No |
None |
Writer script demo
{
"order": {
"hops": [
{
"from": "Reader",
"to": "Writer"
}
]
},
"setting": {
"errorLimit": {
"record": "0"
},
"speed": {
"throttle":true, // If throttle is false, the mbps parameter is ignored and throttling is disabled. If throttle is true, throttling is enabled.
"concurrent":1, // The job concurrency.
"mbps":"12" // The maximum rate in Mbps (1 Mbps = 1 MB/s).
}
},
"steps": [
{
"category": "reader",
"name": "Reader",
"parameter": {
},
"stepType": "stream"
},
{
"category": "writer",
"name": "Writer",
"parameter": {
"datasource":"xxx",
"index": "test-1",
"type": "default",
"cleanup": true,
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"discovery": false,
"primaryKeyInfo":{
"type":"pk",
"fieldDelimiter":",",
"column":[]
},
"batchSize": 1000,
"dynamic":false,
"esPartitionColumn":[
{
"name":"col1",
"comment":"xx",
"type":"STRING"
}
],
"column": [
{
"name": "pk",
"type": "id"
},
{
"name": "col_ip",
"type": "ip"
},
{
"name": "col_array",
"type": "long",
"array": true
},
{
"name": "col_double",
"type": "double"
},
{
"name": "col_long",
"type": "long"
},
{
"name": "col_integer",
"type": "integer"
},
{
"name": "col_keyword",
"type": "keyword"
},
{
"name": "col_text",
"type": "text",
"analyzer": "ik_max_word",
"other_params":
{
"doc_values": false
}
},
{
"name": "col_geo_point",
"type": "geo_point"
},
{
"name": "col_date",
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
{
"name": "col_nested1",
"type": "nested"
},
{
"name": "col_nested2",
"type": "nested"
},
{
"name": "col_object1",
"type": "object"
},
{
"name": "col_object2",
"type": "object"
},
{
"name": "col_integer_array",
"type": "integer",
"array": true
},
{
"name": "col_geo_shape",
"type": "geo_shape",
"tree": "quadtree",
"precision": "10m"
}
]
},
"stepType": "elasticsearch"
}
],
"type": "job",
"version": "2.0"
}
An Elasticsearch instance in a VPC environment may be unreachable from the default resource group. To ensure connectivity for data synchronization, you must use a serverless resource group (recommended) or an exclusive resource group for Data Integration to connect to the VPC. For more information about how to add resource groups, see Serverless resource group.
Writer script parameters
|
Parameter |
Description |
Required |
Default |
|
datasource |
The name of the Elasticsearch data source. If the data source does not exist in DataWorks, create one first. For more information, see Configure an Elasticsearch data source. |
Yes |
None |
|
index |
The name of the index in Elasticsearch. |
Yes |
None |
|
type |
The type of the index in Elasticsearch. |
No |
default |
|
cleanup |
Specifies whether to delete and recreate the target index before writing.
|
No |
false |
|
batchSize |
The number of documents per batch write to Elasticsearch. |
No |
1,000 |
|
trySize |
The number of retries after a failed write to Elasticsearch. |
No |
30 |
|
timeout |
The client timeout period. |
No |
600,000 |
|
discovery |
Specifies whether to enable node discovery for the task.
|
No |
false |
|
compression |
Specifies whether to enable compression for HTTP requests. |
No |
true |
|
multiThread |
Specifies whether to use multiple threads for HTTP requests. |
No |
true |
|
ignoreWriteError |
Specifies whether to ignore write errors. If set to true, the system skips the failed operation and continues writing subsequent data. |
No |
false |
|
ignoreParseError |
Specifies whether to ignore data format parsing errors and continue writing subsequent data. |
No |
true |
|
alias |
An Elasticsearch alias works like a database view. For example, if you create an alias named my_index_alias for the index my_index, operations on my_index_alias apply to my_index. If configured, an alias is created for the specified index after data import completes. |
No |
None |
|
aliasMode |
The alias mode after data import completes. Valid values are append and exclusive.
The system resolves the alias to the actual index name. You can use aliases for index migration, unified queries across multiple indexes, and to implement view-like functionality. |
No |
append |
|
settings |
The index creation settings, in the same format as official Elasticsearch settings. |
No |
None |
|
column |
The column parameter configures the fields in a document. For each field, you can set basic properties such as name and type, and advanced properties such as Analyzer, Format, and Array. The following field types are supported by Elasticsearch:
Notes on column types:
To configure Elasticsearch attributes other than type for a field in column, use the
If you want to write source data to Elasticsearch as an array, you can parse the source data in JSON format or by using a specified delimiter. For more information, see Appendix 2: Write data to Elasticsearch as an array. |
Yes |
None |
|
dynamic |
Specifies whether to use Elasticsearch dynamic mapping to automatically add mappings for new fields in a document.
The default type in Elasticsearch 7.x is _doc. If you use automatic mappings, set the type to _doc and esVersion to You must switch to script mode and add the version parameter: Important
If you encounter field mapping errors, you can enable this parameter to try to resolve the issue. However, this may cause field types to become inconsistent with your expectations or lead to data anomalies. Assess the risks for your data structure before enabling it. |
No |
false |
|
actionType |
Specifies the write action type. Valid values are index and update:
|
No |
index |
|
primaryKeyInfo |
Specifies how to determine the document primary key in Elasticsearch.
|
Yes |
specific |
|
esPartitionColumn |
Specifies whether to enable partitioned writes by setting the Elasticsearch routing parameter.
|
No |
false |
|
enableWriteNull |
Specifies whether to write null fields from the source to Elasticsearch. Valid values:
|
No |
true |
Appendix 2: Writing arrays to Elasticsearch
You can write source data to Elasticsearch as an array using one of two methods.
-
Parse data in JSON format
For example, if the source data is
"[1,2,3,4,5]", parse the data by setting json_array=true. It is then written to Elasticsearch as an array."parameter" : { { "name":"docs_1", "type":"keyword", "json_array":true } } -
Parse data using a delimiter
For example, if the source data is
"1,2,3,4,5", parse the data by setting splitter=",". It is then written to Elasticsearch as an array.NoteA task supports only one delimiter because the splitter parameter is global for the task. You therefore cannot configure different delimiters for multiple array fields. For example, if your source data contains the columns
col1="1,2,3,4,5"andcol2="6-7-8-9-10", you cannot configure a separate delimiter for each column."parameter" : { "column": [ { "name": "docs_2", "array": true, "type": "long" } ], "splitter":","// Note: The splitter parameter must be at the same level as the column parameter. }
Appendix 3: Scenario examples
Scenario 1: Full data pull
-
Background: Pulls an entire Elasticsearch document into a single field.
-
Example configuration:
## reader: Original data in Elasticsearch "hits": [ { "_index": "mutiltest_1", "_type": "_doc", "_id": "IXgdO4MB4GR_1DmrjTXP", "_score": 1.0, "_source": { "feature1": "value1", "feature2": "value2", "feature3": "value3" } }] ## Data Integration Elasticsearch reader configuration "parameter": { "column": [ "content" ], "full":true } ## writer result: Writes one row and one column to the destination. {"_index":"mutiltest_1","_type":"_doc","_id":"IXgdO4MB4GR_1DmrjTXP","_source":{"feature1":"value1","feature2":"value2","feature3":"value3"},"sort":["IXgdO4MB4GR_1DmrjTXP"]}
Scenario 2: Synchronize nested or object field properties
-
Background: Uses a path to access properties of an
objectornestedfield. -
Syntax:
-
property
-
property.sub-property
-
property[0].sub-property
-
-
Code editor configuration:
"multi":{ "multi":true }NoteThis feature is not supported in the codeless UI.
-
Example configuration:
## reader: Original data in Elasticsearch "hits": [ { "_index": "mutiltest_1", "_type": "_doc", "_id": "7XAOOoMB4GR_1Dmrrust", "_score": 1.0, "_source": { "level1": { "level2": [ { "level3": "testlevel3_1" }, { "level3": "testlevel3_2" } ] } } } ] ## Data Integration Elasticsearch reader configuration "parameter": { "column": [ "level1", "level1.level2", "level1.level2[0]", "level1.level2.level3" ], "multi":{ "multi":true } } ## writer result: 1 row, 4 columns column1(level1): {"level2":[{"level3":"testlevel3_1"},{"level3":"testlevel3_2"}]} column2(level1.level2): [{"level3":"testlevel3_1"},{"level3":"testlevel3_2"}] column3(level1.level2[0]): {"level3":"testlevel3_1"} column4(level1.level2.level3): nullNote-
If an ancestor node in the path is an array, the result is
null. For example, retrievinglevel1.level2.level3returnsnullbecauselevel2is an array. To access the property, you must specify an index, such aslevel1.level2[0].level3orlevel1.level2[1].level3. The wildcard syntaxlevel1.level2[*].level3is not supported. -
Keys that contain a period (
.) are not supported. For example, if the data is{"level1.level2":{"level3":"testlevel3_1"}}, the result isnull.
-
Scenario 3: Split an array property into multiple rows
-
Background: For one-to-many relationships, you can unroll an array by splitting each element into a separate row.
-
Syntax:
property[*].sub-property -
Example effect: Source data such as
{ "splitKey": [1, 2, 3, 4, 5] }is transformed into five rows, with each row containing one element from the array. -
Code editor configuration:
"multi":{ "multi":true, "key": "headers" }Note-
In the codeless UI, you can set the split multi-row array column name parameter to achieve the same effect by automatically generating the corresponding script configuration.
-
The value of the property specified by
keymust be a list. Otherwise, an error occurs.
-
-
Example configuration:
## reader: Original data in Elasticsearch [ { "_index": "lmtestjson", "_type": "_doc", "_id": "nhxmIYMBKDL4VkVLyXRN", "_score": 1.0, "_source": { "headers": [ { "remoteip": "192.0.2.1" }, { "remoteip": "192.0.2.2" } ] } }, { "_index": "lmtestjson", "_type": "_doc", "_id": "wRxsIYMBKDL4VkVLcXqf", "_score": 1.0, "_source": { "headers": [ { "remoteip": "192.0.2.3" }, { "remoteip": "192.0.2.4" } ] } } ] ## Data Integration Elasticsearch reader configuration { "column":[ "headers[*].remoteip" ] "multi":{ "multi":true, "key": "headers" } } ## writer result: 4 rows 192.0.2.1 192.0.2.2 192.0.2.3 192.0.2.4
Scenario 4: Deduplicate and merge array properties
-
Background: Deduplicates array elements and merges them into a comma-separated string. This also works with sub-properties such as
name1.name2. Deduplication is based on thetoString()result of each element. -
Syntax:
property[].Including
[]in the column name triggers this deduplication and merge operation. -
Code editor configuration:
"multi":{ "multi":true }NoteThis feature is not supported in the codeless UI.
-
Example configuration:
## reader: Original data in Elasticsearch "hits": [ { "_index": "mutiltest_1", "_type": "_doc", "_id": "4nbUOoMB4GR_1Dmryj8O", "_score": 1.0, "_source": { "feature1": [ "value1", "value1", "value2", "value2", "value3" ] } } ] ## Data Integration Elasticsearch reader configuration "parameter": { "column":[ "feature1[]" ], "multi":{ "multi":true } } ## writer result: 1 row, 1 column "value1,value2,value3"
Scenario 5: Selectively synchronize multiple properties
-
Background: Returns the first non-null property value from a specified list. If all properties are null or absent,
nullis returned. -
Syntax:
property1|property2|...Including the pipe (
|) character in the column name triggers this multi-property selection. -
Code editor configuration:
"multi":{ "multi":true }NoteThis feature is not supported in the codeless UI.
-
Example configuration:
## reader: Original data in Elasticsearch "hits": [ { "_index": "mutiltest_1", "_type": "_doc", "_id": "v3ShOoMB4GR_1DmrZN22", "_score": 1.0, "_source": { "feature1": "feature1", "feature2": [ 1, 2, 3 ], "feature3": { "child": "feature3" } } }] ## Data Integration Elasticsearch reader configuration "parameter": { "column":[ "feature1|feature2|feature3" ], "multi":{ "multi":true } } ## writer result: 1 row, 1 column "feature1"
Scenario 6: Merge and sync multiple properties
-
Background: Concatenates multiple property values into a single comma-separated string.
-
Syntax:
property1,property2,...Including a comma (
,) in the column name triggers this multi-property merge operation. -
Code editor configuration:
"multi":{ "multi":true }NoteThis feature is not supported in the codeless UI.
-
Example configuration:
## reader: Original data in Elasticsearch "hits": [ { "_index": "mutiltest_1", "_type": "_doc", "_id": "v3ShOoMB4GR_1DmrZN22", "_score": 1.0, "_source": { "feature1": "feature1", "feature2": [ 1, 2, 3 ], "feature3": { "child": "feature3" } } }] ## Data Integration Elasticsearch reader configuration "parameter": { "column":[ "feature1,feature2,feature3" ], "multi":{ "multi":true } } ## writer result: 1 row, 1 column "feature1,[1,2,3],{\"child\":\"feature3\"}"
References
Data Integration supports many other data sources. For a complete list, see Supported data sources and synchronization solutions.