Skip to content

Commit

Permalink
feat(es): use simpler logic for generating a query string from filters
Browse files Browse the repository at this point in the history
feat(es): move simple filters to the filter array to save performance

see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/query-dsl-bool-query.html#query-dsl-bool-query

"The clause (query) must appear in matching documents. However unlike must the
score of the query will be ignored. Filter clauses are executed in filter
context, meaning that scoring is ignored and clauses are considered for
caching."
  • Loading branch information
f-necas committed Oct 5, 2023
1 parent 9b4b506 commit 5b321c1
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ElasticsearchService } from './elasticsearch.service'
import { ES_FIXTURE_AGGS_RESPONSE } from '@geonetwork-ui/common/fixtures'
import { EsSearchParams } from '../types/elasticsearch.model'
import { EsSearchParams } from '@geonetwork-ui/api/metadata-converter'

describe('ElasticsearchService', () => {
let service: ElasticsearchService
Expand Down Expand Up @@ -96,26 +96,31 @@ describe('ElasticsearchService', () => {
})
})
describe('#buildPayloadQuery', () => {
it('add any and other fields query_strings', () => {
it('should not add fields query_strings if fieldsSearchFilters Object is empty', () => {
const query = service['buildPayloadQuery'](
{
Org: {
world: true,
},
any: 'hello',
},
{}
{},
['record-1', 'record-2', 'record-3']
)

expect(query).toEqual({
bool: {
filter: [],
should: [],
must: [
filter: [
{
terms: {
isTemplate: ['n'],
},
},
{
ids: {
values: ['record-1', 'record-2', 'record-3'],
},
},
],
should: [],
must: [
{
query_string: {
default_operator: 'AND',
Expand All @@ -130,11 +135,6 @@ describe('ElasticsearchService', () => {
query: 'hello',
},
},
{
query_string: {
query: '(Org:"world")',
},
},
],
must_not: {
terms: {
Expand All @@ -157,14 +157,25 @@ describe('ElasticsearchService', () => {
)
expect(query).toEqual({
bool: {
filter: [],
should: [],
must: [
filter: [
{
terms: {
isTemplate: ['n'],
},
},
{
query_string: {
query: 'Org:("world")',
},
},
{
ids: {
values: ['record-1', 'record-2', 'record-3'],
},
},
],
should: [],
must: [
{
query_string: {
default_operator: 'AND',
Expand All @@ -179,16 +190,6 @@ describe('ElasticsearchService', () => {
query: 'hello',
},
},
{
query_string: {
query: '(Org:"world")',
},
},
{
ids: {
values: ['record-1', 'record-2', 'record-3'],
},
},
],
must_not: {
terms: {
Expand All @@ -203,6 +204,10 @@ describe('ElasticsearchService', () => {
{
Org: {
world: true,
world2: true,
},
name: {
john: true,
},
any: 'hello',
},
Expand All @@ -211,14 +216,25 @@ describe('ElasticsearchService', () => {
)
expect(query).toEqual({
bool: {
filter: [],
should: [],
must: [
filter: [
{
terms: {
isTemplate: ['n'],
},
},
{
query_string: {
query: 'Org:("world" OR "world2") AND name:("john")',
},
},
{
ids: {
values: [],
},
},
],
should: [],
must: [
{
query_string: {
default_operator: 'AND',
Expand All @@ -233,9 +249,38 @@ describe('ElasticsearchService', () => {
query: 'hello',
},
},
],
must_not: {
terms: {
resourceType: ['service', 'map', 'map/static', 'mapDigital'],
},
},
},
})
})
it('handle negative and empty filters', () => {
const query = service['buildPayloadQuery'](
{
Org: {
world: false,
},
name: {},
message: '',
},
{},
[]
)
expect(query).toEqual({
bool: {
filter: [
{
terms: {
isTemplate: ['n'],
},
},
{
query_string: {
query: '(Org:"world")',
query: 'Org:(-"world")',
},
},
{
Expand All @@ -244,6 +289,61 @@ describe('ElasticsearchService', () => {
},
},
],
should: [],
must: [],
must_not: {
terms: {
resourceType: ['service', 'map', 'map/static', 'mapDigital'],
},
},
},
})
})
it('handle filters expressed as queries', () => {
const query = service['buildPayloadQuery'](
{
Org: 'world AND world2',
any: 'hello',
},
{},
[]
)
expect(query).toEqual({
bool: {
filter: [
{
terms: {
isTemplate: ['n'],
},
},
{
query_string: {
query: 'Org:(world AND world2)',
},
},
{
ids: {
values: [],
},
},
],
should: [],
must: [
{
query_string: {
default_operator: 'AND',
fields: [
'resourceTitleObject.langfre^5',
'tag.langfre^4',
'resourceAbstractObject.langfre^3',
'lineageObject.langfre^2',
'any.langfre',
'uuid',
],
query: 'hello',
},
},
],
must_not: {
terms: {
resourceType: ['service', 'map', 'map/static', 'mapDigital'],
Expand All @@ -264,7 +364,7 @@ describe('ElasticsearchService', () => {
)
})
it('escapes special char', () => {
expect(query.bool.must[1].query_string.query).toEqual(
expect(query.bool.must[0].query_string.query).toEqual(
`scot \\(\\)\\{\\?\\[ \\/ test`
)
})
Expand All @@ -287,9 +387,7 @@ describe('ElasticsearchService', () => {
it('adds boosting of 7 for intersecting with it and boosting of 10 on geoms within', () => {
const query = service['buildPayloadQuery'](
{
Org: {
world: true,
},
Org: 'world',
any: 'hello',
},
{},
Expand All @@ -298,13 +396,19 @@ describe('ElasticsearchService', () => {
)
expect(query).toEqual({
bool: {
filter: [],
must: [
filter: [
{
terms: {
isTemplate: ['n'],
},
},
{
query_string: {
query: 'Org:(world)',
},
},
],
must: [
{
query_string: {
default_operator: 'AND',
Expand All @@ -319,11 +423,6 @@ describe('ElasticsearchService', () => {
query: 'hello',
},
},
{
query_string: {
query: '(Org:"world")',
},
},
],
must_not: {
terms: {
Expand Down Expand Up @@ -611,6 +710,7 @@ describe('ElasticsearchService', () => {
filters: {
filter1: { field1: '100' },
filter2: { field2: { value1: true, value3: true } },
filter3: 'my own query',
},
},
myHistogram: {
Expand All @@ -623,14 +723,13 @@ describe('ElasticsearchService', () => {
myFilters: {
filters: {
filter1: {
match: {
field1: '100',
},
query_string: { query: 'field1:(100)' },
},
filter2: {
match: {
field2: { value1: true, value3: true },
},
query_string: { query: 'field2:("value1" OR "value3")' },
},
filter3: {
query_string: { query: 'my own query' },
},
},
},
Expand Down
Loading

0 comments on commit 5b321c1

Please sign in to comment.