我有一个具有相同键的JSON对象。
这些值可以是字符串或数字(以字符串形式),并且在弹性搜索中以相同的方式被索引为文本
[{
"key" : "foo",
"value" : "lisa"
}, {
"key" : "bar",
"value" : "19"
}]
我正在根据以下条件进行比较:
1. match key as "bar"
2. range { "value" : {gt:"10"}}
这没有发生,因为该值被索引为字符串(应为字符串),并且由于字符串“ 2”>字符串“ 10”,因此失败-这是预期的。
关于如何解决此用例的任何建议?
其他信息 :
我发现删除了有关在Elastic Search 7.0+中用作TermRangeQuery的字符串的文档。
参考 :
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html
答案 0 :(得分:2)
您已经遇到过,未使用正确的数据类型的缺点会导致意外的行为。我安静地不明白为什么值可以是数字字符串等。但是考虑到用例,我建议为不同类型的值定义不同的字段。考虑要与之匹配的查询,需要保持键和值字段之间的关系。因此,我建议您定义一个嵌套字段而不是普通对象字段。
不使用对象字段的原因是elastisearch将对象展平,然后对其进行索引。展平对象会导致属性之间的关系丢失。进一步了解此here。
现在,考虑以下示例(弹性7.x):
步骤1:为字段定义具有正确类型的映射
PUT test
{
"mappings": {
"properties": {
"nestedField": {
"type": "nested",
"properties": {
"key": {
"type": "keyword"
},
"stringValue": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"numericValue": {
"type": "integer"
}
}
}
}
}
}
我们创建了一个nestedField
,其中字段key
,stringValue
,类型numericValue
的{{1}}(未分析),keyword
(默认标准分析器和类型为子关键字的子字段(如果需要完全匹配),分别为text
。
第2步:索引文档
integer
请注意如何索引字符串值和数字值。
第3步:根据需要进行查询。
要查询嵌套类型字段,您必须使用nested query。
PUT test/_doc/1
{
"nestedField": [
{
"key": "foo",
"stringValue": "lisa"
},
{
"key": "bar",
"numericValue": 19
}
]
}
PUT test/_doc/2
{
"nestedField": [
{
"key": "foo",
"stringValue": "mary"
},
{
"key": "bar",
"numericValue": 9
}
]
}
上面的查询将仅返回 doc 1 ,因为对于 doc 2 ,即使存在GET test/_search
{
"query": {
"nested": {
"path": "nestedField",
"query": {
"bool": {
"filter": [
{
"term": {
"nestedField.key": "bar"
}
},
{
"range": {
"nestedField.numericValue": {
"gt": 10
}
}
}
]
}
}
}
}
}
,但相关值(key: bar
)也存在不大于10。
答案 1 :(得分:0)
从许多Stack-overflow / Github和其他资源中,它确认此功能不适用于文本。
使用它的唯一方法是在索引时具有相应的数字字段:
[
{ "key" : "foo", "value" : "lisa" },
{ "key" : "bar", "value" : "19", "numericValue" : 19}
]
以及基于数值的索引。稍后在从ES中获取时使用它。
1. match key as "bar"
2. range { "numericValue" : {gt:10}}