# Learning opportunities index

Learning opportunities, services or courses are the basic entity for learning.

## Creating index

To create an index PUT to `https://search.eduplex.eu/example` being `example` the index name. You can add the mapping fields in the body.

See an example here: `https://gitlab.com/eduplex-api/opensearch/-/blob/main/files/index_mapping.json`

## Retrieving entries from index

To search on the index you can do a GET to `https://search.eduplex.eu/example/_search` being `example` the index name and with a body like this it will return all documents from the index.

```
{
  "query": {
    "match_all": {}
  }
}
```

We also have a proxy on our API to build more complex queries allowing to filter, return facets or rank results. Our endpoint allows the following parameters:

* **page**: pagination number.
* **limit**: number of documents per page.
* **text**: text to search.
* **semantic\_text**: same as previous parameter but using vector search with exact knn. You can not use both at the same time.
* **sort\_by**: it allows to sort by the following fields:
  * **title**
  * **total\_price**
  * **ratings**
  * **next\_course**
* **order**: it changes the sorting criteria (`asc` or `desc`)

and the following filters:

* **facets**: an object with different facets to filter. E.g.`{ type: 'online', city: 'Viena' }`.
* **tag**: returns only events associated to a specific tag.
* **category**: returns only events associated to a specific category.
* **seller\_id**: filters by the provider of the learning opportunities.
* **is\_internal**: returns only internal events.
* **has\_exclusive\_tag**: if `false` returns only events without exclusive tags.
* **exclusive\_tags**: if previous filter is set to `false`, also returns events with the specified tags.

## Examples

We use some special parameters to modify the results:

* **track\_scores**: it forces to calculate the score of the documents.
* **functions**: it allows to customize documents ranking scores.
* **score\_mode**: how to calculate the result from all the functions.
* **boost\_mode**: how to apply the `score_mode` to the document score.
* **aggs**: facets to be returned.

### Text search query

```
GET example_index/_search
{
  "from": 0,
  "size": 10,
  "track_scores": true,
  "query": {
    "function_score": {
      "score_mode": "sum",
      "boost_mode": "multiply", 
      "query": {
        "bool": {
          "must": [
            {
              "multi_match": {
                "query": "",
                "fields": [
                  "title^2",
                  "highlight",
                  "tags.display_name",
                  "categories.display_name",
                  "module_titles"
                ],
                "fuzziness": "AUTO",
                "zero_terms_query": "all"
              }
            }
          ]
        }
      },
      "functions": [
        {
          "filter": {
            "term": {
              "provider_is_verified": true
            }
          },
          "weight": 1.2
        },
        {
          "filter": {
            "term": {
              "provider_is_topseller": true
            }
          },
          "weight": 1.2
        },
        {
          "filter": {
            "term": {
              "is_bookable": true
            }
          },
          "weight": 7
        },
        {
          "filter": {
            "term": {
              "has_boost": true
            }
          },
          "weight": 7
        },
        {
          "field_value_factor": {
            "field": "rating_rounded",
            "factor": 0.01,
            "missing": 250
          }
        }
      ]
    }
  },
  "aggs": {
    "tags.display_name": {
      "terms": {
        "field": "tags.display_name.keyword",
        "size": 100
      }
    },
    "language": {
      "terms": {
        "field": "language.keyword",
        "size": 10
      }
    },
    "categories.category": {
      "terms": {
        "field": "categories.category.keyword",
        "size": 100
      }
    },
    "provider.name": {
      "terms": {
        "field": "provider.name.keyword",
        "size": 100
      }
    }
  }
}
```

### Semantic search query

```
GET example_index/_search
{
  "from": 0,
  "size": 10,
  "track_scores": true,
  "query": {
    "function_score": {
      "score_mode": "sum",
      "boost_mode": "multiply", 
      "query": {
        "bool": {
          "must": [
            {
              "bool": {
                "should": [
                  {
                    "script_score": {
                      "query": {
                        "match_all": {}
                      },
                      "script": {
                        "source": "knn_score",
                        "lang": "knn",
                        "params": {
                          "field": "highlight_vector",
                          "query_value": [],
                          "space_type": "innerproduct"
                        }
                      }
                    }
                  }
                ]
              }
            }
          ]
        }
      },
      "functions": [
        {
          "filter": {
            "term": {
              "provider_is_verified": true
            }
          },
          "weight": 1.2
        },
        {
          "filter": {
            "term": {
              "provider_is_topseller": true
            }
          },
          "weight": 1.2
        },
        {
          "filter": {
            "term": {
              "is_bookable": true
            }
          },
          "weight": 7
        },
        {
          "filter": {
            "term": {
              "has_boost": true
            }
          },
          "weight": 7
        },
        {
          "field_value_factor": {
            "field": "rating_rounded",
            "factor": 0.01,
            "missing": 250
          }
        }
      ]
    }
  },
  "aggs": {
    "tags.display_name": {
      "terms": {
        "field": "tags.display_name.keyword",
        "size": 100
      }
    },
    "language": {
      "terms": {
        "field": "language.keyword",
        "size": 10
      }
    },
    "categories.category": {
      "terms": {
        "field": "categories.category.keyword",
        "size": 100
      }
    },
    "provider.name": {
      "terms": {
        "field": "provider.name.keyword",
        "size": 100
      }
    }
  }
}
```
