From 02886815eb7b4cb95d2591e02aa4ffb5e1a21859 Mon Sep 17 00:00:00 2001 From: Mauricio Uyaguari Date: Mon, 18 Mar 2024 17:40:32 -0400 Subject: [PATCH] enhance search for queries in legend query (#2706) --- .../query/api/QueryStoreManager.java | 32 +++++++++---- .../query/model/QuerySearchSpecification.java | 3 +- .../model/QuerySearchTermSpecification.java | 24 ++++++++++ .../query/api/TestQueryStoreManager.java | 45 ++++++++++++++++--- 4 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 legend-engine-application-query/src/main/java/org/finos/legend/engine/application/query/model/QuerySearchTermSpecification.java diff --git a/legend-engine-application-query/src/main/java/org/finos/legend/engine/application/query/api/QueryStoreManager.java b/legend-engine-application-query/src/main/java/org/finos/legend/engine/application/query/api/QueryStoreManager.java index d5a1bf7ed67..a272dc1f7a9 100644 --- a/legend-engine-application-query/src/main/java/org/finos/legend/engine/application/query/api/QueryStoreManager.java +++ b/legend-engine-application-query/src/main/java/org/finos/legend/engine/application/query/api/QueryStoreManager.java @@ -32,10 +32,7 @@ import org.eclipse.collections.api.set.sorted.MutableSortedSet; import org.eclipse.collections.impl.utility.LazyIterate; import org.eclipse.collections.impl.utility.ListIterate; -import org.finos.legend.engine.application.query.model.Query; -import org.finos.legend.engine.application.query.model.QueryEvent; -import org.finos.legend.engine.application.query.model.QuerySearchSpecification; -import org.finos.legend.engine.application.query.model.QueryStoreStats; +import org.finos.legend.engine.application.query.model.*; import org.finos.legend.engine.shared.core.vault.Vault; import javax.lang.model.SourceVersion; @@ -180,15 +177,32 @@ public static void validateQuery(Query query) public List searchQueries(QuerySearchSpecification searchSpecification, String currentUser) { List filters = new ArrayList<>(); - if (searchSpecification.searchTerm != null) + if (searchSpecification.searchTermSpecification != null) { - if (searchSpecification.exactMatchName != null && searchSpecification.exactMatchName) + QuerySearchTermSpecification querySearchTermSpecification = searchSpecification.searchTermSpecification; + if (querySearchTermSpecification.searchTerm == null) { - filters.add(Filters.eq("name", searchSpecification.searchTerm)); + throw new ApplicationQueryException("Query search spec expecting a search term", Response.Status.INTERNAL_SERVER_ERROR); + } + if (querySearchTermSpecification.exactMatchName != null && querySearchTermSpecification.exactMatchName) + { + Bson filter = Filters.eq("name", querySearchTermSpecification.searchTerm); + if (querySearchTermSpecification.includeOwner != null && querySearchTermSpecification.includeOwner) + { + filter = Filters.or(filter,Filters.eq("owner", querySearchTermSpecification.searchTerm)); + } + filters.add(filter); } else { - filters.add(Filters.or(Filters.regex("name", Pattern.quote(searchSpecification.searchTerm), "i"), Filters.eq("id", searchSpecification.searchTerm))); + Bson idFilter = Filters.eq("id", querySearchTermSpecification.searchTerm); + Bson nameFilter = Filters.regex("name", Pattern.quote(querySearchTermSpecification.searchTerm), "i"); + Bson filter = Filters.or(idFilter, nameFilter); + if (querySearchTermSpecification.includeOwner != null && querySearchTermSpecification.includeOwner) + { + filter = Filters.or(idFilter, nameFilter, Filters.regex("owner", Pattern.quote(querySearchTermSpecification.searchTerm), "i")); + } + filters.add(filter); } } if (searchSpecification.showCurrentUserQueriesOnly != null && searchSpecification.showCurrentUserQueriesOnly) @@ -266,7 +280,7 @@ else if (count == 0) } if (notFoundQueries.size() != 0) { - throw new ApplicationQueryException(notFoundQueries.makeString("Can't find queries for the following ID(s):\\n", "\\n", ""), Response.Status.NOT_FOUND); + throw new ApplicationQueryException(notFoundQueries.makeString("Can't find queries for the following ID(s):\\n", "\\n", ""), Response.Status.INTERNAL_SERVER_ERROR); } return matchingQueries; } diff --git a/legend-engine-application-query/src/main/java/org/finos/legend/engine/application/query/model/QuerySearchSpecification.java b/legend-engine-application-query/src/main/java/org/finos/legend/engine/application/query/model/QuerySearchSpecification.java index 415a8a03f7d..291c9a75126 100644 --- a/legend-engine-application-query/src/main/java/org/finos/legend/engine/application/query/model/QuerySearchSpecification.java +++ b/legend-engine-application-query/src/main/java/org/finos/legend/engine/application/query/model/QuerySearchSpecification.java @@ -21,13 +21,12 @@ public class QuerySearchSpecification { - public String searchTerm; + public QuerySearchTermSpecification searchTermSpecification; public List projectCoordinates; public List taggedValues; public List stereotypes; public Integer limit; public Boolean showCurrentUserQueriesOnly; - public Boolean exactMatchName; // This boolean flag helps to perform And condition on filter we apply for tagged values // so that we can search if a query contains all the taggedValues specified in the // search specification diff --git a/legend-engine-application-query/src/main/java/org/finos/legend/engine/application/query/model/QuerySearchTermSpecification.java b/legend-engine-application-query/src/main/java/org/finos/legend/engine/application/query/model/QuerySearchTermSpecification.java new file mode 100644 index 00000000000..c27782eb0ff --- /dev/null +++ b/legend-engine-application-query/src/main/java/org/finos/legend/engine/application/query/model/QuerySearchTermSpecification.java @@ -0,0 +1,24 @@ +// Copyright 2022 Goldman Sachs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package org.finos.legend.engine.application.query.model; + +public class QuerySearchTermSpecification +{ + public String searchTerm; + + public Boolean exactMatchName; + + public Boolean includeOwner; +} diff --git a/legend-engine-application-query/src/test/java/org/finos/legend/engine/application/query/api/TestQueryStoreManager.java b/legend-engine-application-query/src/test/java/org/finos/legend/engine/application/query/api/TestQueryStoreManager.java index f5a81883028..e80e07ca8f6 100644 --- a/legend-engine-application-query/src/test/java/org/finos/legend/engine/application/query/api/TestQueryStoreManager.java +++ b/legend-engine-application-query/src/test/java/org/finos/legend/engine/application/query/api/TestQueryStoreManager.java @@ -24,6 +24,7 @@ import org.finos.legend.engine.application.query.model.QueryParameterValue; import org.finos.legend.engine.application.query.model.QueryProjectCoordinates; import org.finos.legend.engine.application.query.model.QuerySearchSpecification; +import org.finos.legend.engine.application.query.model.QuerySearchTermSpecification; import org.finos.legend.engine.application.query.utils.TestMongoClientProvider; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.StereotypePtr; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.domain.TagPtr; @@ -45,18 +46,21 @@ public class TestQueryStoreManager { static class TestQuerySearchSpecificationBuilder { - public String searchTerm; + public QuerySearchTermSpecification searchTermSpecification; public List projectCoordinates; public List taggedValues; public List stereotypes; public Integer limit; public Boolean showCurrentUserQueriesOnly; - public Boolean exactMatchName; public Boolean combineTaggedValuesCondition; TestQuerySearchSpecificationBuilder withSearchTerm(String searchTerm) { - this.searchTerm = searchTerm; + if (this.searchTermSpecification == null) + { + this.searchTermSpecification = new QuerySearchTermSpecification(); + } + this.searchTermSpecification.searchTerm = searchTerm; return this; } @@ -92,7 +96,21 @@ TestQuerySearchSpecificationBuilder withShowCurrentUserQueriesOnly(Boolean showC TestQuerySearchSpecificationBuilder withExactNameSearch(Boolean exactMatchName) { - this.exactMatchName = exactMatchName; + if (this.searchTermSpecification == null) + { + this.searchTermSpecification = new QuerySearchTermSpecification(); + } + this.searchTermSpecification.exactMatchName = exactMatchName; + return this; + } + + TestQuerySearchSpecificationBuilder withIncludeOwner(Boolean includeOwner) + { + if (this.searchTermSpecification == null) + { + this.searchTermSpecification = new QuerySearchTermSpecification(); + } + this.searchTermSpecification.includeOwner = includeOwner; return this; } @@ -105,13 +123,12 @@ TestQuerySearchSpecificationBuilder withCombineTaggedValuesCondition(Boolean com QuerySearchSpecification build() { QuerySearchSpecification searchSpecification = new QuerySearchSpecification(); - searchSpecification.searchTerm = this.searchTerm; + searchSpecification.searchTermSpecification = this.searchTermSpecification; searchSpecification.projectCoordinates = this.projectCoordinates; searchSpecification.taggedValues = this.taggedValues; searchSpecification.stereotypes = this.stereotypes; searchSpecification.limit = this.limit; searchSpecification.showCurrentUserQueriesOnly = this.showCurrentUserQueriesOnly; - searchSpecification.exactMatchName = this.exactMatchName; searchSpecification.combineTaggedValuesCondition = this.combineTaggedValuesCondition; return searchSpecification; } @@ -541,6 +558,22 @@ public void testGetQueriesWithSearchText() throws Exception Assert.assertEquals(3, queryStoreManager.searchQueries(new TestQuerySearchSpecificationBuilder().withSearchTerm("query").build(), currentUser).size()); } + + @Test + public void testGetQueriesWithSearchTextSpec() throws Exception + { + String currentUser = "user1"; + String user2 = "user2"; + queryStoreManager.createQuery(TestQueryBuilder.create("1", "query1", currentUser).build(), currentUser); + queryStoreManager.createQuery(TestQueryBuilder.create("2", "query2", currentUser).build(), currentUser); + queryStoreManager.createQuery(TestQueryBuilder.create("3", "query3", user2).build(), user2); + Assert.assertEquals(1, queryStoreManager.searchQueries(new TestQuerySearchSpecificationBuilder().withSearchTerm("user2").withIncludeOwner(true).build(), currentUser).size()); + Assert.assertEquals(2, queryStoreManager.searchQueries(new TestQuerySearchSpecificationBuilder().withSearchTerm("user1").withIncludeOwner(true).build(), currentUser).size()); + Assert.assertEquals(3, queryStoreManager.searchQueries(new TestQuerySearchSpecificationBuilder().withSearchTerm("user").withIncludeOwner(true).build(), currentUser).size()); + Assert.assertEquals(0, queryStoreManager.searchQueries(new TestQuerySearchSpecificationBuilder().withSearchTerm("user").withExactNameSearch(true).withIncludeOwner(true).build(), currentUser).size()); + Assert.assertEquals(0, queryStoreManager.searchQueries(new TestQuerySearchSpecificationBuilder().withSearchTerm("user").withIncludeOwner(false).build(), currentUser).size()); + } + @Test public void testGetQueriesForCurrentUser() throws Exception {