如何在ElasticSearch中对数字字段执行全文搜索?

时间:2014-09-15 18:32:53

标签: elasticsearch query-string

问题:

如果不将数字字段转换为字符串,我该如何在其上执行全文搜索?

我正在尝试模仿_all在执行查询时将数字字段动态转换为字符串的行为。

实施例

设定:

curl -XPUT http://localhost:9200/test/items/1 -d '{accountId : 12341234, name:"Bob"}'
curl -XPUT http://localhost:9200/test/items/2 -d '{accountId : 980987, name:"Marry"}'
curl -XPUT http://localhost:9200/test/items/3 -d '{accountId : 234234, name:"Daniel"}'

目的:

查找编号为4的accountId

我做了什么。

我尝试了这两个查询但收到了0次点击。

查询:

curl -XPOST "http://localhost:9200/test/items/_search" -d '{
  "query": {
    "term": {
      "accountId": "4"
    }
  }
}'

curl -XPOST "http://localhost:9200/test/items/_search" -d '{
  "query": {
    "query_string": {
      "query": "4"
    }
  }
}'

输出:

{
    "took": 0,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 0,
        "max_score": null,
        "hits": []
    }
}

2 个答案:

答案 0 :(得分:6)

我建议你为此目的使用ngram tokenizer。

以下是您可能需要的代码示例。您可能希望首先使用要使用的标记器设置分析器设置。

curl -XPUT localhost:9200/test?pretty=true -d '{
  "settings":{
    "analysis":{
      "analyzer":{
        "my_ngram_analyzer":{
          "tokenizer":"my_ngram_tokenizer"
        }
      },
      "tokenizer":{
        "my_ngram_tokenizer":{
          "type":"nGram",
          "token_chars":[
            "letter",
            "digit"
          ]
        }
      }
    }
  }
}'

有关Ngram Tokenizer的更多信息here

然后你应该定义以下映射:

curl -XPUT localhost:9200/test/items/_mapping?pretty=true -d '{
  "items":{
    "properties":{
      "accountId":{
        "analyzer":"my_ngram_analyzer",
        "type":"string"
      },
      "name":{
        "type":"string"
      }
    }
  }
}'

原因' accountId'是一个'字符串'就是Ngram tokenizer不能处理数字字段。

现在您可以查询索引:

curl -XGET localhost:9200/test/_search?pretty=true -d'
{
  "query": {
    "query_string": {
      "default_field": "accountId",
      "query": "4"
    }
  }
}'

您可以找到here我用来测试它的bash脚本。

NB :当然这只是关于如何使用Ngram Tokenizer的演示。我希望它会有所帮助

答案 1 :(得分:4)

创建一个多字段,其中包含一个数字字段以及一个用于搜索的字符串

PUT /test/items/_mapping
{
  "items" : {
    "properties" : {
      "accountId" : {
        "type" : "multi_field",
          "fields" : {
            "numeric" : {
              "type" : "integer",
              "index" : "not_analyzed"
            },
            "text" : {
              "type" : "string",
              "index" : "analyzed"
            }
          }
        }
      }
    }
}

验证您的映射:

GET /test/items/_mapping

<强>输出

{
   "test": {
      "mappings": {
         "items": {
            "properties": {
               "accountId": {
                  "type": "integer",
                  "index": "no",
                  "fields": {
                     "numeric": {
                        "type": "integer"
                     },
                     "text": {
                        "type": "string"
                     }
                  }
               }
            }
         }
      }
   }
}

将您的数据置于弹性搜索中。

现在你可以用字符串进行搜索,但你会得到数字结果:

GET /test/items/_search
{
  "query": {
    "query_string": {
      "default_field": "accountId.text",
      "query": "*4*"
    }
  }
}

<强>输出

{
   "took": 15,
   "timed_out": false,
   "_shards": {
      "total": 4,
      "successful": 4,
      "failed": 0
   },
   "hits": {
      "total": 2,
      "max_score": 1,
      "hits": [
         {
            "_index": "test",
            "_type": "items",
            "_id": "3",
            "_score": 1,
            "_source": {
               "accountId": 234234,
               "name": "Daniel"
            }
         },
         {
            "_index": "test",
            "_type": "items",
            "_id": "1",
            "_score": 1,
            "_source": {
               "accountId": 12341234,
               "name": "Bob"
            }
         }
      ]
   }
}