Bug: fix(opensearch): handle empty free-text query search in global search



Previously, there was no support to add filters in global-search, hence only free-search queries were supported.
Because of this, the following query object was being mandatorily added.
```bash
{
          "multi_match": {
                "type": "phrase",
                "query": "merchant_1726046328",
                "lenient": true
          }
},
``` 

Now, since adding filters is provided as a feature, it is no longer compulsary to have a free-search query in addition to the filters applied.
So if no free-search query is being applied, the query object will have the following:
```bash
{
          "multi_match": {
                "type": "phrase",
                "query": "",
                "lenient": true
          }
},
```
This empty string in the query is resulting in wrong data being fetched when we hit opensearch/elasticsearch using the `/search` API.

Should make changes to incorporate free-search query into the opensearch query only when free-search query is non-empty.
Search should happen only based on filters as expected, when filters are provided and free-search query is empty.
diff --git a/crates/analytics/src/opensearch.rs b/crates/analytics/src/opensearch.rs
index 84a2b9db3d4..e8726840a2e 100644
--- a/crates/analytics/src/opensearch.rs
+++ b/crates/analytics/src/opensearch.rs
@@ -510,14 +510,15 @@ impl OpenSearchQueryBuilder {
         case_sensitive_filters: Vec<&(String, Vec<String>)>,
     ) -> Vec<Value> {
         let mut filter_array = Vec::new();
-
-        filter_array.push(json!({
-            "multi_match": {
-                "type": "phrase",
-                "query": self.query,
-                "lenient": true
-            }
-        }));
+        if !self.query.is_empty() {
+            filter_array.push(json!({
+                "multi_match": {
+                    "type": "phrase",
+                    "query": self.query,
+                    "lenient": true
+                }
+            }));
+        }
 
         let case_sensitive_json_filters = case_sensitive_filters
             .into_iter()

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [x] Bugfix
- [ ] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
Previously, there was no support to add filters in global-search, hence only free-text search queries were supported.
Because of this, the following query object was being mandatorily added.
```bash
{
          "multi_match": {
                "type": "phrase",
                "query": "merchant_1726046328",
                "lenient": true
          }
},
``` 

Now, since adding filters is provided as a feature, it is no longer compulsary to have a free-text search query in addition to the filters applied.
So if no free-text search query is being applied, the query object will have the following:
```bash
{
          "multi_match": {
                "type": "phrase",
                "query": "",
                "lenient": true
          }
},
```
This empty string in the query is resulting in wrong data being fetched when we hit opensearch/elasticsearch using the `/search` API.

Made changes to incorporate free-text search query into the opensearch query only when free-text search query is non-empty.
Now, search will happen only based on filters as expected, when filters are provided and free-text search query is empty.
### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->
Extract correct results when using global search.

## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->

Hit the curl:
```bash
curl --location 'http://localhost:8080/analytics/v1/search' \
--header 'sec-ch-ua-platform: "macOS"' \
--header 'authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTQ5ZTNkMmItMTY5Yi00NzUzLWJmNTQtZDcxMTM2YjRiN2JkIiwibWVyY2hhbnRfaWQiOiJtZXJjaGFudF8xNzI2MDQ2MzI4Iiwicm9sZV9pZCI6Im9yZ19hZG1pbiIsImV4cCI6MTczMjc5Mjk0OCwib3JnX2lkIjoib3JnX1ZwU0hPanNZZkR2YWJWWUpnQ0FKIiwicHJvZmlsZV9pZCI6InByb192NXNGb0hlODBPZWlVbElvbm9jTSIsInRlbmFudF9pZCI6InB1YmxpYyJ9.Q5ruAj8DwAp5XDj1ktFhma4aZXAHSZBmRSw_EnPk4HE' \
--header 'Referer: http://localhost:9000/' \
--header 'sec-ch-ua: "Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"' \
--header 'sec-ch-ua-mobile: ?0' \
--header 'api-key: dev_LZcIA7XeMpnK5satp4CDvjcnHCaeKTBcosyuBBJaknZu1odhFo96cwS0nSdfzuJF' \
--header 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36' \
--header 'Content-Type: application/json' \
--data '{
    "query": "",
    "filters": {
        "status": [
            "CharGed"
        ]
    },
    "timeRange": {
        "startTime": "2024-09-13T00:30:00Z",
        "endTime": "2024-11-27T21:45:00Z"
    }
}'
```
Should get the expected results.
Sample query which will be made:
- when free-text search query is empty and filters are non-empty:

```bash
Index: SessionizerPaymentIntents
Payload: {
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "@timestamp": {
              "gte": "2024-09-13T00:30:00.000Z",
              "lte": "2024-11-27T21:45:00.000Z"
            }
          }
        }
      ],
      "must": [
        {
          "bool": {
            "must": [
              {
                "bool": {
                  "should": [
                    {
                      "term": {
                        "status.keyword": {
                          "value": "CharGed",
                          "case_insensitive": true
                        }
                      }
                    }
                  ],
                  "minimum_should_match": 1
                }
              }
            ]
          }
        },
        {
          "bool": {
            "must": [
              {
                "bool": {
                  "should": [
                    {
                      "bool": {
                        "must": [
                          {
                            "term": {
                              "organization_id.keyword": {
                                "value": "org_VpSHOjsYfDvabVYJgCAJ"
                              }
                            }
                          }
                        ]
                      }
                    }
                  ],
                  "minimum_should_match": 1
                }
              }
            ]
          }
        }
      ]
    }
  },
  "sort": [
    {
      "@timestamp": {
        "order": "desc"
      }
    }
  ]
}
```

- when free-text search query and filters both are non-empty:

```bash
Index: SessionizerPaymentIntents
Payload: {
  "query": {
    "bool": {
      "filter": [
        {
          "multi_match": {
            "type": "phrase",
            "query": "merchant_1726046328",
            "lenient": true
          }
        },
        {
          "range": {
            "@timestamp": {
              "gte": "2024-09-13T00:30:00.000Z",
              "lte": "2024-11-27T21:45:00.000Z"
            }
          }
        }
      ],
      "must": [
        {
          "bool": {
            "must": [
              {
                "bool": {
                  "should": [
                    {
                      "term": {
                        "status.keyword": {
                          "value": "CharGed",
                          "case_insensitive": true
                        }
                      }
                    }
                  ],
                  "minimum_should_match": 1
                }
              }
            ]
          }
        },
        {
          "bool": {
            "must": [
              {
                "bool": {
                  "should": [
                    {
                      "bool": {
                        "must": [
                          {
                            "term": {
                              "organization_id.keyword": {
                                "value": "org_VpSHOjsYfDvabVYJgCAJ"
                              }
                            }
                          }
                        ]
                      }
                    }
                  ],
                  "minimum_should_match": 1
                }
              }
            ]
          }
        }
      ]
    }
  },
  "sort": [
    {
      "@timestamp": {
        "order": "desc"
      }
    }
  ]
}
```
- when free-text search query is non-empty and no filters are applied:

```bash
Index: SessionizerPaymentIntents
Payload: {
  "query": {
    "bool": {
      "filter": [
        {
          "multi_match": {
            "type": "phrase",
            "query": "merchant_1726046328",
            "lenient": true
          }
        },
        {
          "range": {
            "@timestamp": {
              "gte": "2024-09-13T00:30:00.000Z",
              "lte": "2024-11-27T21:45:00.000Z"
            }
          }
        }
      ],
      "must": [
        {
          "bool": {
            "must": [
              {
                "bool": {
                  "should": [
                    {
                      "bool": {
                        "must": [
                          {
                            "term": {
                              "organization_id.keyword": {
                                "value": "org_VpSHOjsYfDvabVYJgCAJ"
                              }
                            }
                          }
                        ]
                      }
                    }
                  ],
                  "minimum_should_match": 1
                }
              }
            ]
          }
        }
      ]
    }
  },
  "sort": [
    {
      "@timestamp": {
        "order": "desc"
      }
    }
  ]
}
```

- when free-text search query is empty and no filters are applied:

```json
{
    "error": {
        "type": "invalid_request",
        "message": "Both query and filters are empty",
        "code": "IR_01"
    }
}
```



## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
