无符号长整型字段类型

编辑

无符号长整型是一种数值字段类型,表示一个无符号 64 位整数,最小值是 0,最大值是 264-1(从 0 到 18446744073709551615,包括两端)。

resp = client.indices.create(
    index="my_index",
    mappings={
        "properties": {
            "my_counter": {
                "type": "unsigned_long"
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my_index',
  body: {
    mappings: {
      properties: {
        my_counter: {
          type: 'unsigned_long'
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "my_index",
  mappings: {
    properties: {
      my_counter: {
        type: "unsigned_long",
      },
    },
  },
});
console.log(response);
PUT my_index
{
  "mappings": {
    "properties": {
      "my_counter": {
        "type": "unsigned_long"
      }
    }
  }
}

无符号长整型可以以数值或字符串形式进行索引,表示范围在 [0, 18446744073709551615] 内的整数值。它们不能有小数部分。

resp = client.bulk(
    index="my_index",
    refresh=True,
    operations=[
        {
            "index": {
                "_id": 1
            }
        },
        {
            "my_counter": 0
        },
        {
            "index": {
                "_id": 2
            }
        },
        {
            "my_counter": 9223372036854776000
        },
        {
            "index": {
                "_id": 3
            }
        },
        {
            "my_counter": 18446744073709552000
        },
        {
            "index": {
                "_id": 4
            }
        },
        {
            "my_counter": 18446744073709552000
        }
    ],
)
print(resp)
response = client.bulk(
  index: 'my_index',
  refresh: true,
  body: [
    {
      index: {
        _id: 1
      }
    },
    {
      my_counter: 0
    },
    {
      index: {
        _id: 2
      }
    },
    {
      my_counter: 9_223_372_036_854_776_000
    },
    {
      index: {
        _id: 3
      }
    },
    {
      my_counter: 18_446_744_073_709_552_000
    },
    {
      index: {
        _id: 4
      }
    },
    {
      my_counter: 18_446_744_073_709_552_000
    }
  ]
)
puts response
const response = await client.bulk({
  index: "my_index",
  refresh: "true",
  operations: [
    {
      index: {
        _id: 1,
      },
    },
    {
      my_counter: 0,
    },
    {
      index: {
        _id: 2,
      },
    },
    {
      my_counter: 9223372036854776000,
    },
    {
      index: {
        _id: 3,
      },
    },
    {
      my_counter: 18446744073709552000,
    },
    {
      index: {
        _id: 4,
      },
    },
    {
      my_counter: 18446744073709552000,
    },
  ],
});
console.log(response);
POST /my_index/_bulk?refresh
{"index":{"_id":1}}
{"my_counter": 0}
{"index":{"_id":2}}
{"my_counter": 9223372036854775808}
{"index":{"_id":3}}
{"my_counter": 18446744073709551614}
{"index":{"_id":4}}
{"my_counter": 18446744073709551615}

词条查询接受任何数值或字符串形式的数字。

resp = client.search(
    index="my_index",
    query={
        "term": {
            "my_counter": 18446744073709552000
        }
    },
)
print(resp)
response = client.search(
  index: 'my_index',
  body: {
    query: {
      term: {
        my_counter: 18_446_744_073_709_552_000
      }
    }
  }
)
puts response
const response = await client.search({
  index: "my_index",
  query: {
    term: {
      my_counter: 18446744073709552000,
    },
  },
});
console.log(response);
GET /my_index/_search
{
    "query": {
        "term" : {
            "my_counter" : 18446744073709551615
        }
    }
}

范围查询的词条可以包含带小数部分的值。在这种情况下,Elasticsearch 会将它们转换为整数值:gtegt 词条转换为最接近的向上取整的整数,而 ltlte 范围转换为最接近的向下取整的整数。

建议将范围作为字符串传递,以确保它们在解析时不会丢失精度。

resp = client.search(
    index="my_index",
    query={
        "range": {
            "my_counter": {
                "gte": "9223372036854775808",
                "lte": "18446744073709551615"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'my_index',
  body: {
    query: {
      range: {
        my_counter: {
          gte: '9223372036854775808',
          lte: '18446744073709551615'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "my_index",
  query: {
    range: {
      my_counter: {
        gte: "9223372036854775808",
        lte: "18446744073709551615",
      },
    },
  },
});
console.log(response);
GET /my_index/_search
{
    "query": {
        "range" : {
            "my_counter" : {
                "gte" : "9223372036854775808",
                "lte" : "18446744073709551615"
            }
        }
    }
}

排序值

编辑

对于在 unsigned_long 字段上进行排序的查询,如果该文档的值在长整型值的范围内,Elasticsearch 会为特定文档返回 long 类型的排序值;如果该值超出此范围,则返回 BigInteger 类型的排序值。

REST 客户端需要能够处理 JSON 中的大整数值,以正确支持此字段类型。

resp = client.search(
    index="my_index",
    query={
        "match_all": {}
    },
    sort={
        "my_counter": "desc"
    },
)
print(resp)
response = client.search(
  index: 'my_index',
  body: {
    query: {
      match_all: {}
    },
    sort: {
      my_counter: 'desc'
    }
  }
)
puts response
const response = await client.search({
  index: "my_index",
  query: {
    match_all: {},
  },
  sort: {
    my_counter: "desc",
  },
});
console.log(response);
GET /my_index/_search
{
    "query": {
        "match_all" : {}
    },
    "sort" : {"my_counter" : "desc"}
}

存储字段

编辑

unsigned_long 的存储字段以 String 形式存储和返回。

聚合

编辑

对于 terms 聚合,与排序值类似,使用 LongBigInteger 值。对于其他聚合,值将转换为 double 类型。

脚本值

编辑

默认情况下,unsigned_long 字段的脚本值以 Java 有符号 Long 的形式返回,这意味着大于 Long.MAX_VALUE 的值将显示为负值。您可以使用 Long.compareUnsigned(long, long)Long.divideUnsigned(long, long)Long.remainderUnsigned(long, long) 来正确处理这些值。

例如,下面的脚本返回计数器除以 10 的值。

resp = client.search(
    index="my_index",
    query={
        "match_all": {}
    },
    script_fields={
        "count10": {
            "script": {
                "source": "Long.divideUnsigned(doc['my_counter'].value, 10)"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'my_index',
  body: {
    query: {
      match_all: {}
    },
    script_fields: {
      "count10": {
        script: {
          source: "Long.divideUnsigned(doc['my_counter'].value, 10)"
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "my_index",
  query: {
    match_all: {},
  },
  script_fields: {
    count10: {
      script: {
        source: "Long.divideUnsigned(doc['my_counter'].value, 10)",
      },
    },
  },
});
console.log(response);
GET /my_index/_search
{
    "query": {
        "match_all" : {}
    },
    "script_fields": {
        "count10" : {
          "script": {
            "source": "Long.divideUnsigned(doc['my_counter'].value, 10)"
          }
        }
    }
}

或者,您可以使用字段 API 将脚本中的无符号长整型视为 BigInteger。例如,以下脚本将 my_counter 视为 BigInteger,默认值为 BigInteger.ZERO

"script": {
    "source": "field('my_counter').asBigInteger(BigInteger.ZERO)"
}

对于需要返回 float 或 double 值的脚本,您可以进一步将 BigInteger 值转换为 double 或 float

resp = client.search(
    index="my_index",
    query={
        "script_score": {
            "query": {
                "match_all": {}
            },
            "script": {
                "source": "field('my_counter').asBigInteger(BigInteger.ZERO).floatValue()"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'my_index',
  body: {
    query: {
      script_score: {
        query: {
          match_all: {}
        },
        script: {
          source: "field('my_counter').asBigInteger(BigInteger.ZERO).floatValue()"
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "my_index",
  query: {
    script_score: {
      query: {
        match_all: {},
      },
      script: {
        source:
          "field('my_counter').asBigInteger(BigInteger.ZERO).floatValue()",
      },
    },
  },
});
console.log(response);
GET /my_index/_search
{
    "query": {
        "script_score": {
          "query": {"match_all": {}},
          "script": {
            "source": "field('my_counter').asBigInteger(BigInteger.ZERO).floatValue()"
          }
        }
    }
}

混合数值类型的查询

编辑

支持混合数值类型的搜索,其中之一是 unsigned_long,但排序查询除外。因此,在一个索引中具有 unsigned_long 类型,而在另一个索引中具有 long 类型的相同字段名称的两个索引之间的排序查询不会产生正确的结果,必须避免。如果需要这种排序,则可以使用基于脚本的排序。

支持跨多种数值类型的聚合,其中之一是 unsigned_long。在这种情况下,值将转换为 double 类型。