我有一个keyword
类型的字段,可以包含数字或字符串。如果该字段不包含任何字母,我想点击该文档。我该怎么办?
我的索引映射如下:
{
"mappings": {
"Entry": {
"properties": {
"testField": {
"type": "keyword"
}
}
}
}
}
我的文档如下:
{
"testField":"123abc"
}
或
{
"testField": "456789"
}
我已经尝试过查询:
{
"query": {
"range": {
"gte": 0,
"lte": 2000000
}
}
}
,但仍然命中123abc
。我该如何设计,以使我只打中该特定字段中带有数字的文档?
答案 0 :(得分:1)
Afaik,Elasticsearch对此没有直接解决方案。
相反,您需要编写一个Script Query。以下是您要寻找的东西:
POST <your_index_name>/_search
{
"query": {
"bool": {
"must": [
{
"script": {
"script": {
"lang": "painless",
"source": """
try{
String temp = doc['testField'].value;
int a = Integer.parseInt(temp);
if(a instanceof Integer)
return true;
}catch(NumberFormatException e){
return false;
}
"""
}
}
}
]
}
}
}
希望有帮助!
答案 1 :(得分:1)
还有另一种更理想的选择来实现您想要的目标。您可以利用ingest API pipelines,并使用script
processor来在建立索引时创建另一个数字字段,然后可以在搜索时更有效地使用它。
下面的提取管道包含一个script
处理器,它将创建另一个名为numField
的字段,该字段仅包含数字值。
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"script": {
"source": """
ctx.numField = /\D/.matcher(ctx.testField).replaceAll("");
"""
}
}
]
},
"docs": [
{
"_source": {
"testField": "123"
}
},
{
"_source": {
"testField": "abc123"
}
},
{
"_source": {
"testField": "123abc"
}
},
{
"_source": {
"testField": "abc"
}
}
]
}
使用包含字母数字内容的4个不同文档来模拟该管道,将得出以下结果:
{
"docs" : [
{
"doc" : {
"_index" : "_index",
"_type" : "_type",
"_id" : "_id",
"_source" : {
"numField" : "123",
"testField" : "123"
},
"_ingest" : {
"timestamp" : "2019-05-09T04:14:51.448Z"
}
}
},
{
"doc" : {
"_index" : "_index",
"_type" : "_type",
"_id" : "_id",
"_source" : {
"numField" : "123",
"testField" : "abc123"
},
"_ingest" : {
"timestamp" : "2019-05-09T04:14:51.448Z"
}
}
},
{
"doc" : {
"_index" : "_index",
"_type" : "_type",
"_id" : "_id",
"_source" : {
"numField" : "123",
"testField" : "123abc"
},
"_ingest" : {
"timestamp" : "2019-05-09T04:14:51.448Z"
}
}
},
{
"doc" : {
"_index" : "_index",
"_type" : "_type",
"_id" : "_id",
"_source" : {
"numField" : "",
"testField" : "abc"
},
"_ingest" : {
"timestamp" : "2019-05-09T04:14:51.448Z"
}
}
}
]
}
为文档using this pipeline编制索引后,您可以在numField
而不是testField
上运行范围查询。与其他解决方案(对不起,@ Kamal)相比,它将转移脚本编制负担,使其在索引编制时每个文档仅运行一次,而不是在搜索时每次在文档上运行。
{
"query": {
"range": {
"numField": {
"gte": 0,
"lte": 2000000
}
}
}
}