Elasticsearch override field value in search results

Viewed 29

The use case is that, I want to hide product price(change to 0) if a user is not logged in.

PUT /products
{
  "mappings": {
    "properties": {
        "price": {
        "type": "scaled_float",
        "scaling_factor": 100
      }
    }
  }
}
POST /products/_doc
{
  "price": 101
}
POST /products/_doc
{
  "price": 102
}
POST /products/_doc
{
  "price": 103
}

I try to use runtime_mapping with the following script, but the result still has the original data.

GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "runtime_mappings": {
    "price": {
      "type": "double",
      "script": "if(0 == 1) {emit(333);} else{emit(222);}"
    }
  }
}

What do I miss? Is it the script condition invalid?

Thanks.

-- Edit --

I expect all the price to be 222. But the original price is returned.

Expected out put:

{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "products",
        "_id" : "XXphNoMBcFxgyV6Mwe1-",
        "_score" : 1.0,
        "_source" : {
          "price" : 222
        }
      },
      {
        "_index" : "products",
        "_id" : "XnphNoMBcFxgyV6Mye2c",
        "_score" : 1.0,
        "_source" : {
          "price" : 222
        }
      },
      {
        "_index" : "products",
        "_id" : "X3phNoMBcFxgyV6M0e2W",
        "_score" : 1.0,
        "_source" : {
          "price" : 222
        }
      },
      {
        "_index" : "products",
        "_id" : "YHphNoMBcFxgyV6M3u0V",
        "_score" : 1.0,
        "_source" : {
          "price" : 222
        }
      }
    ]
  }
}

Actual output:

{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "products",
        "_id" : "XXphNoMBcFxgyV6Mwe1-",
        "_score" : 1.0,
        "_source" : {
          "price" : 101
        }
      },
      {
        "_index" : "products",
        "_id" : "XnphNoMBcFxgyV6Mye2c",
        "_score" : 1.0,
        "_source" : {
          "price" : 102
        }
      },
      {
        "_index" : "products",
        "_id" : "X3phNoMBcFxgyV6M0e2W",
        "_score" : 1.0,
        "_source" : {
          "price" : 105
        }
      },
      {
        "_index" : "products",
        "_id" : "YHphNoMBcFxgyV6M3u0V",
        "_score" : 1.0,
        "_source" : {
          "price" : 0
        }
      }
    ]
  }
}
1 Answers

After retry on the example in the official doc, I realized that I missed out the fields key in query body.

GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "runtime_mappings": {
    "price": {
      "type": "double",
      "script": "if(0 == 1) {emit(333);} else{emit(222);}"
    }
  },
  "fields": ["price"]
}

Now I get both the original and script fields.

Related