Elasticsearch to conditionally match all tags, categories and keywords

I am trying to build a music search function, using Elasticsearch 9.15.

I am currently using .NET client. I am happy to just get the idea how it would look like via DSL, so that I can replicate it for .NET.

Every piece of music can be like below json:

{
    "_source": {
        "duration": 258,
        "ratings": 67.8,
        "addedTime": "2024-09-25T16:22:53.0427917+10:00",
        "createdTime": "2024-09-25T16:22:53.0447736+10:00",
        "favorites": 9999,
        "votesUp": 7778,
        "votesDown": 4212,
        "languageId": 2,
        "tags": [
          {
            "tagId": 3,
            "languageId": 2,
            "name": "Australia"
          },
          {
            "tagId": 2,
            "languageId": 2,
            "name": "Good"
          }
        ],
        "categories": [
          {
            "categoryId": 1,
            "languageId": 2,
            "name": "Love"
          },
          {
            "categoryId": 3,
            "languageId": 2,
            "name": "Soft"
          }
        ],
        "singers": [
          {
            "singerId": 2,
            "fullName": "Bee Gees",
            "firstName": "Bee",
            "lastName": "Gees"
          }
        ],
        "qualities": [
          {
            "qualityId": 2,
            "resolution": 160
          },
          {
            "qualityId": 3,
            "resolution": 320
          },
          {
            "qualityId": 4,
            "resolution": 640
          }
        ],
        "id": "161d12b7-bcb6-40ab-9ea9-44683f15be45",
        "uniqueId": 1,
        "providerId": 1,
        "sourceKey": "BeeGees0001",
        "title": "Night Fever",
        "title_en": "Night Fever",
        "title_cn": "夜热",
        "title_de": "Nachtfieber",
        "title_ja": "ナイトフィーバー"
      }
    }

What I am trying to achieve is:

  1. When there is no keyword specified, it would try to match the following criteria:
    a). duration, which is in seconds, it should be within a range (minDuration parameter <= duration <= maxDuration parameter)
    b). it should match all the tags, if tags parameter provided
    c). it should match all the categories, if categories parameter provided
    c). it should match all singers, if singers parameter provided
    d). it should match all the sound qualities, if qualities parameter provided

    then, it should sort by ratings desc, then by favorites desc, then by votesUp / (votesDown + votesUp) desc.

  2. When there is keyword specified, it will match same criteria as above(no keyword), PLUS it will additionally match any of the titles (title, title_en, title_cn, title_de, title_ja), and any of singers by the full name, and any of tags by the name, and any of the categories by the name

In a nutshell, the criteria are all conditional, depending on whether certain corresponding parameter is provided or not.

I am not sure how to "chain" all those conditions together.

Any thoughts?

Hi there @Wilson_Chen and welcome to the community!

What you're looking for is a Boolean query. This will allow you to identify multiple queries (such as ranges and term queries, etc) that you want to be returned.

Then, you'll want to add sort criteria on the fields that you want.

Good luck!

From Elastic Search to Elasticsearch