我通过使用以下映射创建了索引:
put test1
{
"mappings": {
"type1": {
"properties": {
"age": {
"type": "text",
"fields": {
"raw": {
"type": "keyword",
"ignore_above": 32766
}
}
}
}
}
}
}
将以下文档添加到索引中:
PUT test1/type1/1/_create
{
"age":50
}
PUT test1/type1/2/_create
{
"age":100
}
PUT test1/type1/3/_create
{
"age":150
}
PUT test1/type1/4/_create
{
"age":200
}
我已经使用以下范围查询来获取结果:
GET test1/_search
{
"query": {
"range" : {
"age" : {
"lte" : 150
}
}
}
}
它给了我以下答复:
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 1,
"hits": [
{
"_index": "test1",
"_type": "type1",
"_id": "2",
"_score": 1,
"_source": {
"age": 100
}
},
{
"_index": "test1",
"_type": "type1",
"_id": "3",
"_score": 1,
"_source": {
"age": 150
}
}
]
}
}
以上未显示年龄为50的文档的响应仅显示年龄为100和150。由于50也小于200。这有什么问题? 谁能帮助我获得有效的结果? 在我的模式年龄字段中输入文本,我不想更改它。
如何获得有效结果?
答案 0 :(得分:2)
由于年龄字段类型为文本,因此范围查询使用字母顺序。因此结果是正确的:
如果仅在age
字段中提取数字,则应将age
字段类型更改为number
,或添加另一个内部字段作为数字,就像处理{{1 }}内部字段。
答案 1 :(得分:1)
更新:已在本地系统上测试,并且可以正常运行。
注意:理想情况下,您希望映射正确无误,但是如果没有其他选择,而且您不是决定映射的人,那么您仍然可以通过遵循此步骤来实现。
从ES版本6.3开始,请尝试此操作。
GET test1/type1/_search
{
"query": {
"bool" : {
"must" : {
"script" : {
"script" : {
"source": "Integer.parseInt(doc['age.raw'].value) <= 150",
"lang": "painless"
}
}
}
}
}
}
参考来源:
https://www.elastic.co/guide/en/elasticsearch/reference/6.3/query-dsl-script-query.html
https://discuss.elastic.co/t/painscript-script-cast-string-as-int/97034
答案 2 :(得分:0)
您在映射中的字段年龄的类型设置为文本。这就是为什么它在50> 150的情况下进行字典排序。请使用长数据类型。 https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html