Skip to content

Commit c17786f

Browse files
allisonsuarezkristenarmesGolodhros
authored and
Zachary Ruiz
committed
feat: update search service to use new search mappings (amundsen-io#1832)
* chore: update search service to use new search mappings Signed-off-by: Allison Suarez Miranda <[email protected]> * needed fields back Signed-off-by: Allison Suarez Miranda <[email protected]> * updated index name to point to new index Signed-off-by: Allison Suarez Miranda <[email protected]> * Added deprecation warning log to old ES client Signed-off-by: Allison Suarez Miranda <[email protected]> * made fixtures match new mappings for tests Signed-off-by: Allison Suarez Miranda <[email protected]> * fixed other unit ests Signed-off-by: Allison Suarez Miranda <[email protected]> * lint Signed-off-by: Allison Suarez Miranda <[email protected]> * remove print and import unused Signed-off-by: Allison Suarez Miranda <[email protected]> * added docs explaining how to transition to /v2/search Signed-off-by: Allison Suarez Miranda <[email protected]> * bit more doc Signed-off-by: Allison Suarez Miranda <[email protected]> * change to keep BW compatibility and add new functionality Signed-off-by: Allison Suarez Miranda <[email protected]> * a bit of cleanup and comments for clarity Signed-off-by: Allison Suarez Miranda <[email protected]> * more cleanup and manual testing of new search Signed-off-by: Allison Suarez Miranda <[email protected]> * updated all unit tests and initialize proxy classes according to bww comp functionality Signed-off-by: Allison Suarez Miranda <[email protected]> * lint Signed-off-by: Allison Suarez Miranda <[email protected]> * updated docs Signed-off-by: Allison Suarez Miranda <[email protected]> * fixed flake and mypy errors Signed-off-by: Allison Suarez Miranda <[email protected]> * more mypy Signed-off-by: Allison Suarez Miranda <[email protected]> * sort imports in v3 Signed-off-by: Allison Suarez Miranda <[email protected]> * implemented most feedback need to do more manual testing and run unit tests + linter Signed-off-by: Allison Suarez Miranda <[email protected]> * fixed import Signed-off-by: Allison Suarez Miranda <[email protected]> * updated doc Signed-off-by: Allison Suarez Miranda <[email protected]> * oops Signed-off-by: Allison Suarez Miranda <[email protected]> * fix Signed-off-by: Allison Suarez Miranda <[email protected]> * fix mypy issue Signed-off-by: Allison Suarez Miranda <[email protected]> * type removed Signed-off-by: Allison Suarez Miranda <[email protected]> * more config cleanup and some clarifications Signed-off-by: Allison Suarez Miranda <[email protected]> * fix: toggle filter should clear when off (amundsen-io#1848) * fix: toggle filter should clear when off Signed-off-by: Allison Suarez Miranda <[email protected]> * lint fix Signed-off-by: Allison Suarez Miranda <[email protected]> * updated unit test Signed-off-by: Allison Suarez Miranda <[email protected]> * suggestion Signed-off-by: Allison Suarez Miranda <[email protected]> * Refactoring various column details and adding type metadata to the table metadata FE model (amundsen-io#1847) Signed-off-by: Kristen Armes <[email protected]> * fix: fixes tour not resetting on different pages (amundsen-io#1849) Signed-off-by: Marcos Iglesias <[email protected]> * fix: better behavior for search filters (amundsen-io#1852) * fix: better behavior for application of filters Signed-off-by: Allison Suarez Miranda <[email protected]> * explicit comparison to None Signed-off-by: Allison Suarez Miranda <[email protected]> * 2nd round of feedback plus more context Signed-off-by: Allison Suarez Miranda <[email protected]> * added filters change from different PR and removed deprecated configs Signed-off-by: Allison Suarez Miranda <[email protected]> * chore: update search service to use new search mappings Signed-off-by: Allison Suarez Miranda <[email protected]> * needed fields back Signed-off-by: Allison Suarez Miranda <[email protected]> * updated index name to point to new index Signed-off-by: Allison Suarez Miranda <[email protected]> * Added deprecation warning log to old ES client Signed-off-by: Allison Suarez Miranda <[email protected]> * made fixtures match new mappings for tests Signed-off-by: Allison Suarez Miranda <[email protected]> * fixed other unit ests Signed-off-by: Allison Suarez Miranda <[email protected]> * lint Signed-off-by: Allison Suarez Miranda <[email protected]> * remove print and import unused Signed-off-by: Allison Suarez Miranda <[email protected]> * added docs explaining how to transition to /v2/search Signed-off-by: Allison Suarez Miranda <[email protected]> * bit more doc Signed-off-by: Allison Suarez Miranda <[email protected]> * change to keep BW compatibility and add new functionality Signed-off-by: Allison Suarez Miranda <[email protected]> * a bit of cleanup and comments for clarity Signed-off-by: Allison Suarez Miranda <[email protected]> * more cleanup and manual testing of new search Signed-off-by: Allison Suarez Miranda <[email protected]> * updated all unit tests and initialize proxy classes according to bww comp functionality Signed-off-by: Allison Suarez Miranda <[email protected]> * lint Signed-off-by: Allison Suarez Miranda <[email protected]> * updated docs Signed-off-by: Allison Suarez Miranda <[email protected]> * fixed flake and mypy errors Signed-off-by: Allison Suarez Miranda <[email protected]> * more mypy Signed-off-by: Allison Suarez Miranda <[email protected]> * sort imports in v3 Signed-off-by: Allison Suarez Miranda <[email protected]> * implemented most feedback need to do more manual testing and run unit tests + linter Signed-off-by: Allison Suarez Miranda <[email protected]> * fixed import Signed-off-by: Allison Suarez Miranda <[email protected]> * updated doc Signed-off-by: Allison Suarez Miranda <[email protected]> * oops Signed-off-by: Allison Suarez Miranda <[email protected]> * fix Signed-off-by: Allison Suarez Miranda <[email protected]> * fix mypy issue Signed-off-by: Allison Suarez Miranda <[email protected]> * type removed Signed-off-by: Allison Suarez Miranda <[email protected]> * more config cleanup and some clarifications Signed-off-by: Allison Suarez Miranda <[email protected]> * 2nd round of feedback plus more context Signed-off-by: Allison Suarez Miranda <[email protected]> * added filters change from different PR and removed deprecated configs Signed-off-by: Allison Suarez Miranda <[email protected]> * Revert "Merge branch 'asm-search-with-new-mappings' of github.com:amundsen-io/amundsen into asm-search-with-new-mappings" This reverts commit 49c5c34, reversing changes made to e14b541. * fix args kwards Signed-off-by: Allison Suarez Miranda <[email protected]> * deprecating config Signed-off-by: Allison Suarez Miranda <[email protected]> * deprecating config Signed-off-by: Allison Suarez Miranda <[email protected]> * args fix Signed-off-by: Allison Suarez Miranda <[email protected]> * readme update Signed-off-by: Allison Suarez Miranda <[email protected]> * conf Signed-off-by: Allison Suarez Miranda <[email protected]> * flake Signed-off-by: Allison Suarez Miranda <[email protected]> * fixed new Signed-off-by: Allison Suarez Miranda <[email protected]> * type ignore Signed-off-by: Allison Suarez Miranda <[email protected]> * https://peps.python.org/pep-0484/\#arbitrary-argument-lists-and-default-argument-values Signed-off-by: Allison Suarez Miranda <[email protected]> * Empty-Commit Co-authored-by: Kristen Armes <[email protected]> Co-authored-by: Marcos Iglesias <[email protected]>
1 parent 82c3670 commit c17786f

File tree

40 files changed

+1444
-401
lines changed

40 files changed

+1444
-401
lines changed

docs/tutorials/how-to-search-effective.md

-156
This file was deleted.

docs/tutorials/search-v2_1.md

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# New Amundsen Search
2+
3+
Amundsen Search now has a new API `v2` which supports searching all resources indexed in Amundsen and handles filtered and unfiltered search through the `/v2/search` endpoint as opposed to the old endpoints which were defined per resource. This new API also supports updating documents in Elasticsearch through `/v2/document`. The old endpoints relied on the `ElasticsearchProxy` proxy which doesn't support `v2`. The frontend service has been migrated to the `v2` API, so the old search proxy cannot be used with `amundsen-frontend >= 4.0.0`.
4+
There is `ElasticsearchProxyV2` which supports `v2` and has feature parity with the old API. However this proxy doesn't include any enhancements beyond multi-valued filters with AND/OR logic because further enhancements (like search fuzziness, stemmings, highlighting, etc.)require new mappings to be created by databuilder.
5+
Finally there is `ElasticsearchProxyV2_1`. This latets proxy supports all new search enhacements that rely on new Elasticsearch mappings and it's also accessible throught `/v2/search` and `/v2/document`. This proxy class is configured by default but it will fall back to `ElasticsearchProxyV2` if it cannot find the new mappings in Elasticsearch.
6+
7+
The goal of this tutorial is to explain what the new search functionality offers, how to transition into using `/v2/search` search service endpoint out of the box as well as how to customize it ahead of deprecation of the old search endpoints. The updated search service offers [fuzziness](https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#fuzziness), word [stemming](https://www.elastic.co/guide/en/elasticsearch/reference/8.1/stemming.html), and [boosted search ranking](https://www.elastic.co/guide/en/elasticsearch/reference/8.1/query-dsl-rank-feature-query.html) based on usage.
8+
9+
## Elasticsearch Context
10+
11+
In order for search to function, metadata for all searchable resources configured is indexed into Elasticsearch with a databuilder task and then Elasticsearch is queried via the search service. In Elasticsearch there are two main concepts that are fundamental to understanding how search works, [mappings](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html) and [search queries](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-your-data.html). Mappings define how fields are indexed into Elasticsearch by specifying the types of fields and how text fields are analyzed. The queries should then be written with the mapping in mind since there certain field types are required to perform certain types of queries efficiently.
12+
13+
## Transitioning to `/v2/search`
14+
15+
In order to ensure a smooth transition from our previous search functionality to a version which supports these new features follow these steps:
16+
17+
### Index Metadata to Elasticsearch Using New Mappings
18+
1. Bump to `amundsen-databuilder >= 6.8.0`
19+
2. Configure [SearchMetadatatoElasticsearchTask](https://github.com/amundsen-io/amundsen/blob/main/databuilder/databuilder/task/search/search_metadata_to_elasticsearch_task.py)
20+
- Make sure to configure it using a different index alias. So for example if previously the configuration for writing new ES indices was **(A)** for this task **(B)** must be configured instead for each resource.
21+
**(A)** `ELASTICSEARCH_ALIAS_CONFIG_KEY → table_search_index`
22+
**(B)** `ELASTICSEARCH_ALIAS_CONFIG_KEY → table_search_index_v2_1`
23+
- This way the previous index is preserved and the new index aliases have the [new mappings](https://github.com/amundsen-io/amundsen/blob/main/databuilder/databuilder/task/search/document_mappings.py) that enable all of the functionality mentioned above.
24+
- Note this task will use the mappings already provided in this file and default queries to extract metadata from neo4j. Elasticsearch mappings can be customized by extending the mapping classes and configuring the task to use the custom mapping via `MAPPING_CLASS`
25+
Queries to extract metadata from neo4j can be customized and configured through `CYPHER_QUERY_CONFIG_KEY`.
26+
3. Run the task.
27+
4. Verify that your ES mappings match the [new mapping definitions](https://github.com/amundsen-io/amundsen/blob/main/databuilder/databuilder/task/search/document_mappings.py) by running this directly on Elasticsearch.
28+
- `GET new_table_search_index`
29+
30+
### Configuring the Search Service
31+
32+
1. Bump to `amundsen-search >= 4.0.0`
33+
2. Configure the [Elasticsearch ES_PROXY_CLIENT to use ELASTICSEARCH_V2_1](https://github.com/amundsen-io/amundsen/blob/main/search/search_service/config.py#L18), which is enabled by default in the latest version of search unless configured differently.
34+
- You can customize the search query by providing a custom client. You can create your own client by extending the class from `es_proxy_v2_1.py` (ex: `class MyESClient(ElasticsearchProxyV2_1):`) and overwritting any of the functions provided to change the query.
35+
3. (OPTIONAL) If the alias your new mappings are indexed under differs from `{resource}_search_index_v2_1` make sure to configure the correct string template by adding `ES_ALIAS_TEMPLATE = 'my_{resource}_search_index_alias'` to the config with your custom alias name.
36+
37+
### Use the latest version of Frontend
38+
1. Make sure you are using `amundsen-frontend >= 4.0.0` which calls the search service `/v2/search` endpoint.

frontend/amundsen_application/static/.betterer.results

+13-7
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ exports[`eslint`] = {
341341
[60, 2, 51, "refToSelf should be placed after componentWillUnmount", "3412474606"],
342342
[105, 6, 13, "Do not use setState in componentDidUpdate", "57229240"]
343343
],
344-
"js/components/Table/index.tsx:1457853108": [
344+
"js/components/Table/index.tsx:2629931458": [
345345
[314, 8, 65, "A control must be associated with a text label.", "1026764939"]
346346
],
347347
"js/components/Table/table.story.tsx:3074937505": [
@@ -447,7 +447,7 @@ exports[`eslint`] = {
447447
[19, 2, 8, "Assignment to function parameter \'resource\'.", "2131237679"],
448448
[20, 2, 248, "Expected a default case.", "1034339850"]
449449
],
450-
"js/ducks/tableMetadata/api/v0.ts:4194065289": [
450+
"js/ducks/tableMetadata/api/v0.ts:4044823741": [
451451
[80, 8, 23, "Use object destructuring.", "1142306891"],
452452
[139, 23, -4311, "Expected to return a value at the end of arrow function.", "5381"]
453453
],
@@ -458,7 +458,7 @@ exports[`eslint`] = {
458458
"js/ducks/tableMetadata/owners/sagas.ts:3725515638": [
459459
[7, 0, 69, "\`../types\` import should occur before import of \`./reducer\`", "3326352266"]
460460
],
461-
"js/ducks/tableMetadata/reducer.ts:1012064960": [
461+
"js/ducks/tableMetadata/reducer.ts:3872576896": [
462462
[416, 6, 93, "Unexpected lexical declaration in case block.", "4098864482"]
463463
],
464464
"js/ducks/tags/api/v0.ts:2781466514": [
@@ -486,6 +486,9 @@ exports[`eslint`] = {
486486
[130, 6, 12, "Assignment to function parameter \'currentIndex\'.", "2078922066"],
487487
[171, 4, 10, "Assignment to function parameter \'columnType\'.", "460876587"]
488488
],
489+
"js/features/ColumnList/index.tsx:4269963749": [
490+
[219, 2, 871, "Arrow function expected no return value.", "1083254797"]
491+
],
489492
"js/features/ExpandableUniqueValues/index.spec.tsx:2032191364": [
490493
[13, 0, 48, "\`./testDataBuilder\` import should occur before import of \`.\`", "3767205268"]
491494
],
@@ -638,9 +641,12 @@ exports[`eslint`] = {
638641
"js/pages/TableDetailPage/FrequentUsers/index.tsx:14585253": [
639642
[62, 11, 26, "A form label must be associated with a control.", "2816972347"]
640643
],
641-
"js/pages/TableDetailPage/ListSortingDropdown/index.tsx:286421664": [
642-
[64, 25, 1, "\'_\' is defined but never used.", "177658"],
643-
[67, 14, 204, "A control must be associated with a text label.", "3622841199"]
644+
"js/pages/TableDetailPage/ListSortingDropdown/index.spec.tsx:1478300175": [
645+
[174, 14, 34, "Use array destructuring.", "2024515814"]
646+
],
647+
"js/pages/TableDetailPage/ListSortingDropdown/index.tsx:3178023015": [
648+
[62, 25, 1, "\'_\' is defined but never used.", "177658"],
649+
[65, 14, 204, "A control must be associated with a text label.", "3622841199"]
644650
],
645651
"js/pages/TableDetailPage/ReportTableIssue/index.tsx:2627382373": [
646652
[168, 15, 20, "Script URL is a form of eval.", "3959800777"],
@@ -684,7 +690,7 @@ exports[`eslint`] = {
684690
"js/pages/TableDetailPage/WatermarkLabel/index.tsx:2189911402": [
685691
[29, 22, 21, "Must use destructuring props assignment", "587844958"]
686692
],
687-
"js/pages/TableDetailPage/index.tsx:2270284782": [
693+
"js/pages/TableDetailPage/index.tsx:324823146": [
688694
[159, 2, 20, "key should be placed after componentDidUpdate", "3916788587"],
689695
[205, 6, 13, "Do not use setState in componentDidUpdate", "57229240"]
690696
],

frontend/amundsen_application/static/js/components/Table/index.spec.tsx

+3-7
Original file line numberDiff line numberDiff line change
@@ -730,12 +730,10 @@ describe('Table', () => {
730730
});
731731
});
732732

733-
describe('when currentSelectedKey is passed', () => {
733+
describe('when currentSelectedIndex is passed', () => {
734734
it('adds the selected row styling to the selected row', () => {
735735
const { wrapper } = setup({
736-
options: {
737-
currentSelectedKey: 'database://cluster.schema/table/rowName',
738-
},
736+
options: { currentSelectedIndex: 0 },
739737
});
740738
const expected = 'ams-table-row is-selected-row';
741739
const actual = wrapper
@@ -748,9 +746,7 @@ describe('Table', () => {
748746

749747
it('does not add the selected row styling to a non selected row', () => {
750748
const { wrapper } = setup({
751-
options: {
752-
currentSelectedKey: 'database://cluster.schema/table/rowName',
753-
},
749+
options: { currentSelectedIndex: 0 },
754750
});
755751
const expected = 'ams-table-row false';
756752
const actual = wrapper

frontend/amundsen_application/static/js/components/Table/index.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export interface TableOptions {
4242
onExpand?: (rowValues: any, index: number) => void;
4343
onCollapse?: (rowValues: any, index: number) => void;
4444
emptyMessage?: string;
45-
currentSelectedKey?: string;
45+
currentSelectedIndex?: number;
4646
}
4747

4848
export interface TableProps {
@@ -201,7 +201,7 @@ const Table: React.FC<TableProps> = ({
201201
onExpand,
202202
onCollapse,
203203
preExpandRow,
204-
currentSelectedKey,
204+
currentSelectedIndex,
205205
} = options;
206206
const fields = columns.map(({ field }) => field);
207207
const rowStyles = { height: `${rowHeight}px` };
@@ -231,7 +231,7 @@ const Table: React.FC<TableProps> = ({
231231
<React.Fragment key={`index:${index}`}>
232232
<tr
233233
className={`ams-table-row ${
234-
currentSelectedKey === item.key && 'is-selected-row'
234+
currentSelectedIndex === item.col_index && 'is-selected-row'
235235
} ${
236236
expandRow && expandedRows.includes(index)
237237
? 'has-child-expanded'
@@ -251,7 +251,7 @@ const Table: React.FC<TableProps> = ({
251251
onCollapse={onCollapse}
252252
rowValues={item}
253253
onClick={setExpandedRows}
254-
isSelectedRow={currentSelectedKey === item.key}
254+
isSelectedRow={currentSelectedIndex === item.col_index}
255255
/>
256256
) : (
257257
<td />

frontend/amundsen_application/static/js/components/Table/testDataBuilder.tsx

+3-18
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,9 @@ import * as React from 'react';
55
import { Dropdown, MenuItem } from 'react-bootstrap';
66

77
const defaultData = [
8-
{
9-
name: 'rowName',
10-
type: 'rowType',
11-
value: 1,
12-
key: 'database://cluster.schema/table/rowName',
13-
},
14-
{
15-
name: 'rowName2',
16-
type: 'rowType2',
17-
value: 2,
18-
key: 'database://cluster.schema/table/rowName2',
19-
},
20-
{
21-
name: 'rowName3',
22-
type: 'rowType3',
23-
value: 3,
24-
key: 'database://cluster.schema/table/rowName3',
25-
},
8+
{ name: 'rowName', type: 'rowType', value: 1, col_index: 0 },
9+
{ name: 'rowName2', type: 'rowType2', value: 2, col_index: 1 },
10+
{ name: 'rowName3', type: 'rowType3', value: 3, col_index: 2 },
2611
];
2712

2813
const defaultColumns = [

frontend/amundsen_application/static/js/ducks/tableMetadata/api/helpers.spec.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -140,13 +140,11 @@ describe('helpers', () => {
140140

141141
describe('parseNestedColumns', () => {
142142
it('Adds a children array to a column with nested columns', () => {
143-
const tableKey = 'database://cluster.schema/table';
144143
const testColumn = [
145144
{
146145
badges: [],
147146
col_type: 'row(col1 varchar, col2 varchar)',
148147
description: '',
149-
key: tableKey + '/amount',
150148
name: 'amount',
151149
sort_order: 0,
152150
nested_level: 0,
@@ -176,7 +174,7 @@ describe('helpers', () => {
176174
stats: [],
177175
},
178176
];
179-
const actual = Helpers.processColumns(testColumn, tableKey);
177+
const actual = Helpers.processColumns(testColumn);
180178
expect(actual[0].children).toEqual(expectedChildren);
181179
});
182180
});

0 commit comments

Comments
 (0)