From 59ea09f9ee7df07bd75cbb64faf72793e19127e4 Mon Sep 17 00:00:00 2001
From: Peter Pisljar <peter.pisljar@elastic.co>
Date: Wed, 14 Sep 2022 09:01:33 +0200
Subject: [PATCH] allows passing multiple dataviews to buildEsQuery (#140162)

---
 .../src/es_query/build_es_query.ts            |  4 +-
 .../src/es_query/from_filters.test.ts         | 39 +++++++++++++++++++
 .../kbn-es-query/src/es_query/from_filters.ts | 27 ++++++++-----
 3 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/packages/kbn-es-query/src/es_query/build_es_query.ts b/packages/kbn-es-query/src/es_query/build_es_query.ts
index 1a0ac9cef15ee..497d38a0530cf 100644
--- a/packages/kbn-es-query/src/es_query/build_es_query.ts
+++ b/packages/kbn-es-query/src/es_query/build_es_query.ts
@@ -45,7 +45,7 @@ function removeMatchAll<T>(filters: T[]) {
  * @public
  */
 export function buildEsQuery(
-  indexPattern: DataViewBase | undefined,
+  indexPattern: DataViewBase | DataViewBase[] | undefined,
   queries: AnyQuery | AnyQuery[],
   filters: Filter | Filter[],
   config: EsQueryConfig = {
@@ -60,7 +60,7 @@ export function buildEsQuery(
   const validQueries = queries.filter(isOfQueryType).filter((query) => has(query, 'query'));
   const queriesByLanguage = groupBy(validQueries, 'language');
   const kueryQuery = buildQueryFromKuery(
-    indexPattern,
+    Array.isArray(indexPattern) ? indexPattern[0] : indexPattern,
     queriesByLanguage.kuery,
     { allowLeadingWildcards: config.allowLeadingWildcards },
     {
diff --git a/packages/kbn-es-query/src/es_query/from_filters.test.ts b/packages/kbn-es-query/src/es_query/from_filters.test.ts
index 78b719ccc0e62..d17b0de3768b1 100644
--- a/packages/kbn-es-query/src/es_query/from_filters.test.ts
+++ b/packages/kbn-es-query/src/es_query/from_filters.test.ts
@@ -15,6 +15,7 @@ describe('build query', () => {
   const indexPattern: DataViewBase = {
     fields,
     title: 'dataView',
+    id: '1',
   };
 
   describe('buildQueryFromFilters', () => {
@@ -201,5 +202,43 @@ describe('build query', () => {
       const result = buildQueryFromFilters(filters, indexPattern, { nestedIgnoreUnmapped: true });
       expect(result.filter).toEqual(expectedESQueries);
     });
+
+    test('should work with multiple data views', () => {
+      const indexPattern2: DataViewBase = {
+        fields,
+        title: 'dataView',
+        id: '2',
+      };
+
+      const filters = [
+        {
+          query: { query_string: { query: 'foo' } },
+          meta: { index: '1' },
+        },
+        {
+          query: { query_string: { query: 'bar' } },
+          meta: { index: '2' },
+        },
+      ] as Filter[];
+
+      const result = buildQueryFromFilters(filters, [indexPattern, indexPattern2], {
+        ignoreFilterIfFieldNotInIndex: false,
+      });
+
+      expect(result.filter).toMatchInlineSnapshot(`
+        Array [
+          Object {
+            "query_string": Object {
+              "query": "foo",
+            },
+          },
+          Object {
+            "query_string": Object {
+              "query": "bar",
+            },
+          },
+        ]
+      `);
+    });
   });
 });
diff --git a/packages/kbn-es-query/src/es_query/from_filters.ts b/packages/kbn-es-query/src/es_query/from_filters.ts
index 871ff77026b54..2200648a52c4f 100644
--- a/packages/kbn-es-query/src/es_query/from_filters.ts
+++ b/packages/kbn-es-query/src/es_query/from_filters.ts
@@ -64,27 +64,34 @@ export interface EsQueryFiltersConfig {
  * @public
  */
 export const buildQueryFromFilters = (
-  filters: Filter[] = [],
-  indexPattern: DataViewBase | undefined,
+  inputFilters: Filter[] = [],
+  inputDataViews: DataViewBase | DataViewBase[] | undefined,
   { ignoreFilterIfFieldNotInIndex = false, nestedIgnoreUnmapped }: EsQueryFiltersConfig = {
     ignoreFilterIfFieldNotInIndex: false,
   }
 ): BoolQuery => {
-  filters = filters.filter((filter) => filter && !isFilterDisabled(filter));
+  const filters = inputFilters.filter((filter) => filter && !isFilterDisabled(filter));
+  const indexPatterns = Array.isArray(inputDataViews) ? inputDataViews : [inputDataViews];
+
+  const findIndexPattern = (id: string | undefined) => {
+    return indexPatterns.find((index) => index?.id === id) || indexPatterns[0];
+  };
 
   const filtersToESQueries = (negate: boolean) => {
     return filters
       .filter((f) => !!f)
       .filter(filterNegate(negate))
-      .filter(
-        (filter) => !ignoreFilterIfFieldNotInIndex || filterMatchesIndex(filter, indexPattern)
-      )
+      .filter((filter) => {
+        const indexPattern = findIndexPattern(filter.meta?.index);
+        return !ignoreFilterIfFieldNotInIndex || filterMatchesIndex(filter, indexPattern);
+      })
       .map((filter) => {
-        return migrateFilter(filter, indexPattern);
+        const indexPattern = findIndexPattern(filter.meta?.index);
+        const migratedFilter = migrateFilter(filter, indexPattern);
+        return handleNestedFilter(migratedFilter, indexPattern, {
+          ignoreUnmapped: nestedIgnoreUnmapped,
+        });
       })
-      .map((filter) =>
-        handleNestedFilter(filter, indexPattern, { ignoreUnmapped: nestedIgnoreUnmapped })
-      )
       .map(cleanFilter)
       .map(translateToQuery);
   };