Skip to content

Commit 5202917

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents 3263cee + 43730bd commit 5202917

File tree

1 file changed

+223
-15
lines changed

1 file changed

+223
-15
lines changed

README.md

Lines changed: 223 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,235 @@
1-
# TSDX Bootstrap
1+
# AWS ElasticSearch Model
2+
A small library that simplifies [AWS ElasticSearch Service](https://aws.amazon.com/elasticsearch-service/) integration into serverless applications build with AWS Lambda
23

3-
This project was bootstrapped with [TSDX](https://github.com/jaredpalmer/tsdx).
4+
## Install
5+
```
6+
npm install aws-elasticsearch-model
7+
```
8+
or
9+
```
10+
yarn install aws-elasticsearch-model
11+
```
412

5-
## Local Development
13+
## Intitialize
614

7-
Below is a list of commands you will probably find useful.
15+
```typescript
16+
import AWS from 'aws-sdk';
17+
import ElasticModel from 'aws-elasticsearch-model';
818

9-
### `npm start` or `yarn start`
19+
/*
20+
ElasticModel uses aws-sdk's default behaviour to obtain region + credentials from your environment.
21+
If you would like to set these manually, you can set them on aws-sdk:
22+
*/
23+
AWS.config.update({region: 'eu-west-1'});
1024

11-
Runs the project in development/watch mode. Your project will be rebuilt upon changes. TSDX has a special logger for you convenience. Error messages are pretty printed and formatted for compatibility VS Code's Problems tab.
25+
const elasticModel = new ElasticModel({
26+
host: 'https://my-aws-elasticsearch-domain.eu-west-1.es.amazonaws.com',
27+
index: 'users'
28+
});
1229

13-
<img src="https://user-images.githubusercontent.com/4060187/52168303-574d3a00-26f6-11e9-9f3b-71dbec9ebfcb.gif" width="600" />
30+
```
1431

15-
Your library will be rebuilt if you make edits.
32+
## Index your data
33+
ElasticModel will automatically create [elasticsearch index](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html) if missing
1634

17-
### `npm run build` or `yarn build`
35+
```typescript
36+
const users = [
37+
{
38+
id: '0ee2fa0e-28c5-49d5-9156-5018f7263615',
39+
email: 'Ibrahim.Sawayn93@hotmail.com',
40+
name: 'Khalil_Lebsack'
41+
},
42+
{
43+
id: '04a425bf-07ed-4369-bc6f-e51ac414b93c',
44+
email: 'Rafaela_Kohler74@gmail.com',
45+
name: 'Ayden_Rodriguez'
46+
},
47+
{
48+
id: '81ab442a-b693-47e5-b9e1-6807cbb7978e',
49+
email: 'Howell73@gmail.com',
50+
name: 'Carlotta_Kuhic37'
51+
}
52+
];
1853

19-
Bundles the package to the `dist` folder.
20-
The package is optimized and bundled with Rollup into multiple formats (CommonJS, UMD, and ES Module).
54+
const result = await elasticModel.bulkIndex(users);
55+
```
2156

22-
<img src="https://user-images.githubusercontent.com/4060187/52168322-a98e5b00-26f6-11e9-8cf6-222d716b75ef.gif" width="600" />
57+
## Sync your index with DynamoDB table using Lambda
58+
Quite often DynamoDB table is used as a source of trouth to store data and ElasticSearch is used to provide advanced seach capabilities. In this case a Lambda function is required to sync data betwean DynamoDB table and ElasticSearch index
2359

24-
### `npm test` or `yarn test`
60+
Attach this lambda handler to your DynamoDB table and it will sync all the data changes with ElasticSearch
2561

26-
Runs the test watcher (Jest) in an interactive mode.
27-
By default, runs tests related to files changed since the last commit.
62+
```typescript
63+
import {DynamoDBStreamEvent} from 'aws-lambda';
64+
import ElasticModel from 'aws-elasticsearch-model';
65+
66+
const elasticModel = new ElasticModel({
67+
host: 'https://my-aws-elasticsearch-domain.eu-west-1.es.amazonaws.com',
68+
index: 'users'
69+
});
70+
71+
export const handler = async (event: DynamoDBStreamEvent) => {
72+
return elasticModel.indexFromDynamoDBStream(event);
73+
};
74+
75+
```
76+
77+
Your lambda function needs to have a role attached to it that allows to access your ElasticSearch instance
78+
79+
```
80+
{
81+
"Version": "2012-10-17",
82+
"Statement": [
83+
{
84+
"Action": [
85+
"es:ESHttpPost",
86+
"es:ESHttpPut",
87+
"es:ESHttpDelete"
88+
],
89+
"Resource": "arn:aws:es:AWS_REGION:AWS_ACCOUNT_ID:domain/my-elasticsearch-domain/*",
90+
"Effect": "Allow"
91+
}
92+
]
93+
}
94+
```
95+
96+
## Query your data
97+
[queryBuilder](src/index.ts#L145) method will return a chainable function that allows easily build complex queries for elasticsearch with a simple, predictable api.
98+
99+
It uses [bodybuilder](https://github.com/danpaz/bodybuilder) package by [Daniel Paz-Soldan](https://github.com/danpaz)
100+
101+
To get full builder api check the [docs here](https://bodybuilder.js.org/docs/)
102+
103+
To execure the query call `query.exec()` at the end
104+
105+
```typescript
106+
const query = elasticModel
107+
.queryBuilder()
108+
.filter('match', 'email', 'Ibrahim.Sawayn93@hotmail.com')
109+
.orFilter('match', 'email', 'Rafaela_Kohler74@gmail.com');
110+
111+
const result = await query.exec();
112+
```
113+
114+
You can also run a search query directly. The query above is equivalent to:
115+
116+
```typescript
117+
const result = await elasticModel.search({
118+
query: {
119+
bool: {
120+
filter: {
121+
bool: {
122+
must: {
123+
match: {
124+
email: 'Ibrahim.Sawayn93@hotmail.com'
125+
}
126+
},
127+
should: [
128+
{
129+
match: {
130+
email: 'Rafaela_Kohler74@gmail.com'
131+
}
132+
}
133+
]
134+
}
135+
}
136+
}
137+
}
138+
});
139+
```
140+
141+
## Use custom mapping and index settings
142+
By default ElasticSearch will try to guess your data stracture but you can provide your own index mapping to improve search performance.
143+
144+
```typescript
145+
const elasticModel = new ElasticModel({
146+
host: 'https://my-aws-elasticsearch-domain.eu-west-1.es.amazonaws.com',
147+
index: 'users',
148+
settings: {
149+
analysis: {
150+
analyzer: {
151+
email: {
152+
type: 'custom',
153+
tokenizer: 'uax_url_email'
154+
}
155+
}
156+
}
157+
},
158+
mapping: {
159+
id: {
160+
type: 'keyword'
161+
},
162+
email: {
163+
type: 'text',
164+
analyzer: 'email'
165+
},
166+
name: {
167+
type: 'text'
168+
}
169+
}
170+
});
171+
```
172+
173+
Read more about [mappings](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html) and [settings](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-modules-settings)
174+
175+
## Use custom `id` field
176+
By defaul ElasticModel will use `id` field in your data to privide unique `id` to ElasticSearch but it can be customized.
177+
178+
```typescript
179+
const elasticModel = new ElasticModel({
180+
host: 'https://my-aws-elasticsearch-domain.eu-west-1.es.amazonaws.com',
181+
index: 'users',
182+
idField: 'userId'
183+
});
184+
```
185+
186+
When you sync your data with DynamoDB `DynamoDBStreamEvent` event provides `Keys` object that will contain a composit hash key of your item. For example if you have `hashKey: 'userId', rangeKey: 'createdAt'` by default only `userId` filed will be selected as `id` (if it is specified in config).
187+
188+
This behaviour can be customized:
189+
190+
```typescript
191+
export const handler = async (event: DynamoDBStreamEvent) => {
192+
return elasticModel.indexFromDynamoDBStream(event, keys => {
193+
// keys: {userId, createdAt}
194+
// use base64 encoded userId
195+
return new Buffer(keys.userId).toString('base64');
196+
});
197+
};
198+
```
199+
200+
## Exclude fields
201+
To completly exclude fields from ElasticSearch you can provide `excludedFields` option. This option will remove the field before data is submited.
202+
203+
```typescript
204+
const elasticModel = new ElasticModel({
205+
host: 'https://my-aws-elasticsearch-domain.eu-west-1.es.amazonaws.com',
206+
index: 'users',
207+
excludedFields: ['email']
208+
});
209+
```
210+
If you want field value to be stored but not indexed or available for search you can set `index: false` parameter in mapping
211+
212+
```typescript
213+
const elasticModel = new ElasticModel({
214+
host: 'https://my-aws-elasticsearch-domain.eu-west-1.es.amazonaws.com',
215+
index: 'users',
216+
mapping: {
217+
id: {
218+
type: 'keyword'
219+
},
220+
email: {
221+
index: false,
222+
type: 'text'
223+
},
224+
name: {
225+
type: 'text'
226+
}
227+
}
228+
});
229+
```
230+
231+
## Access ElasticSearch client
232+
ElasticModel provides direct access to [elasticsearch client](https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/16.x/index.html). You can access client instance as `elasticModel.client`
233+
234+
## Avaliable config options
235+
You can find all config options [here](src/index.ts#L72)

0 commit comments

Comments
 (0)