Getting proper sorting of product in category

Hello,

I'm trying to make more fancy sorting but I faced an issue by issue maybe because I'm newbie to the elasticsearch. Let me explain the situation:
I have a category with ID 1 for example but when someone opened it the category must list all products from it and it's subcategories. They must be sorted by first match.

Here is a example request via Bulk API with my data:

{"index":{"_index":"products","_type":"product","_id":431}},
{"ProductID":431,"ProductPrice":11.79,"Categories":[{"CategoryId":3057,"Position":156},{"CategoryId":3061,"Position":1}]},
{"index":{"_index":"products","_type":"product","_id":432}},
{"ProductID":432,"ProductPrice":9.19,"Categories":[{"CategoryId":3061,"Position":43}]}

Here is my mapping:

{
  "products": {
    "mappings": {
      "product": {
        "properties": {
          "Categories": {
            "type": "nested",
            "dynamic": "strict",
            "properties": {
              "CategoryId": {
                "type": "long"
              },
              "Position": {
                "type": "long"
              }
            }
          },
          "ProductID": {
            "type": "long"
          }
        }
      }
    }
  }
}

My query to get results is something like this:

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "Categories",
            "query": {
              "function_score": {
                "script_score": {
                  "script": {
                    "lang": "painless",
                    "source": "double boost_factor = 9999; if (ctx._source.containsKey('Categories')) { for (item in ctx._source.Categories) { if (item.CategoryId == params.key) { boost_factor = item[params.value]; break; } } if (boost_factor == 9999) { boost_factor = 1337; } } else { boost_factor = 7331; } return boost_factor;",
                    "params": {
                      "key": "CategoryId",
                      "value": "Position"
                    }
                  }
                },
                "query": {
                  "bool": {
                    "should": [
                      {
                        "match": {
                          "Categories.CategoryId": 3056
                        }
                      },
                      {
                        "match": {
                          "Categories.CategoryId": 3057
                        }
                      },
                      {
                        "match": {
                          "Categories.CategoryId": 3061
                        }
                      }
                    ]
                  }
                },
                "score_mode": "max",
                "boost_mode": "replace"
              }
            },
            "score_mode": "max"
          }
        }
      ]
    }
  },
  "sort": {
    "_score": {
      "order": "asc"
    },
    "_id": {
      "order": "asc"
    }
  }
}

When I run the query I'm always getting the same result:

{
  "error": {
    "root_cause": [
      {
        "type": "script_exception",
        "reason": "compile error",
        "script_stack": [
          "... boost_factor = 9999; if (ctx._source.containsKey(' ...",
          "                             ^---- HERE"
        ],
        "script": "double boost_factor = 9999; if (ctx._source.containsKey('Categories')) { for (item in ctx._source.Categories) { if (item.CategoryId == params.key) { boost_factor = item[params.value]; break; } } if (boost_factor == 9999) { boost_factor = 1337; } } else { boost_factor = 7331; } return boost_factor;",
        "lang": "painless"
      }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
      {
        "shard": 0,
        "index": "products",
        "node": "R6TZu3XNTleJDewXtUbnuw",
        "reason": {
          "type": "query_shard_exception",
          "reason": "script_score: the script could not be loaded",
          "index_uuid": "aFCVPFpNREW_ba8jF-lI8g",
          "index": "products",
          "caused_by": {
            "type": "script_exception",
            "reason": "compile error",
            "script_stack": [
              "... boost_factor = 9999; if (ctx._source.containsKey(' ...",
              "                             ^---- HERE"
            ],
            "script": "double boost_factor = 9999; if (ctx._source.containsKey('Categories')) { for (item in ctx._source.Categories) { if (item.CategoryId == params.key) { boost_factor = item[params.value]; break; } } if (boost_factor == 9999) { boost_factor = 1337; } } else { boost_factor = 7331; } return boost_factor;",
            "lang": "painless",
            "caused_by": {
              "type": "illegal_argument_exception",
              "reason": "Variable [ctx] is not defined."
            }
          }
        }
      }
    ],
    "caused_by": {
      "type": "script_exception",
      "reason": "compile error",
      "script_stack": [
        "... boost_factor = 9999; if (ctx._source.containsKey(' ...",
        "                             ^---- HERE"
      ],
      "script": "double boost_factor = 9999; if (ctx._source.containsKey('Categories')) { for (item in ctx._source.Categories) { if (item.CategoryId == params.key) { boost_factor = item[params.value]; break; } } if (boost_factor == 9999) { boost_factor = 1337; } } else { boost_factor = 7331; } return boost_factor;",
      "lang": "painless",
      "caused_by": {
        "type": "illegal_argument_exception",
        "reason": "Variable [ctx] is not defined."
      }
    }
  },
  "status": 400
}

I don't know why I'm always getting the following error "Variable [ctx] is not defined." because in every example I saw (even in official documentation) everyone used "ctx".

I've looked at this example Field_value_factor on nested field with dynamic mapping but I can't see the working state of the query.

Any help will be much appreciated thank you in advance!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.