Elasticsearch mac地址搜索/映射

时间:2013-07-24 15:58:19

标签: search indexing mapping elasticsearch mac-address

当我进行部分搜索(半个八位字节)时,我无法获得mac地址搜索以返回正确的结果。我的意思是,如果我找到确切的mac地址,我得到的结果,但如果尝试搜索部分搜索,如“00:19:9”,我没有得到任何东西,直到我完成八位字节。

任何人都可以指出我应该使用哪种映射来索引它或者我应该使用哪种搜索查询?

curl -XDELETE http://localhost:9200/ap-test
curl -XPUT http://localhost:9200/ap-test

curl -XPUT http://localhost:9200/ap-test/devices/1 -d '
{
  "user" : "James Earl",
  "macaddr" : "00:19:92:00:71:80"
}'

curl -XPUT http://localhost:9200/ap-test/devices/2 -d '
{
  "user" : "Earl",
  "macaddr" : "00:19:92:00:71:82"
}'

curl -XPUT http://localhost:9200/ap-test/devices/3 -d '
{
  "user" : "James Edward",
  "macaddr" : "11:19:92:00:71:80"
}'

curl -XPOST 'http://localhost:9200/ap-test/_refresh'
curl -XGET http://localhost:9200/ap-test/devices/_mapping?pretty

当我找到完全匹配时,我得到了正确的....

curl -XPOST http://localhost:9200/ap-test/devices/_search -d '
{
    "query" : {
        "query_string" : {
            "query":"\"00\\:19\\:92\\:00\\:71\\:80\""
        }
    }
}'

# RETURNS:

{
  "took": 6,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.57534903,
    "hits": [
      {
        "_index": "ap-test",
        "_type": "devices",
        "_id": "1",
        "_score": 0.57534903,
        "_source": {
          "user": "James Earl",
          "macaddr": "00:19:92:00:71:80"
        }
      }
    ]
  }
}

但是,我需要能够匹配部分mac地址搜索,如下所示:

curl -XPOST http://localhost:9200/ap-test/devices/_search -d '
{
    "query" : {
        "query_string" : {
            "query":"\"00\\:19\\:9\""
        }
    }
}'

# RETURNS 0 instead of returning 2 of them 

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

那么,我应该使用什么样的映射?有没有更好的查询字符串来实现这一目标?顺便说一句,使用'query_string'和'text'之间的区别是什么?

2 个答案:

答案 0 :(得分:2)

看起来您根本没有定义映射,这意味着elasticsearch会猜测您的数据类型并使用标准映射。

对于字段macaddr,这将被识别为字符串,并将使用标准字符串分析器。这个分析器会在空白和标点符号上分解字符串,留下由数字对组成的标记。例如"00:19:92:00:71:80"会被标记为00 19 92 00 71 80。当您搜索相同的标记时,将会发生。

你想要的是定义一个分析器,它将"00:19:92:00:71:80"转换为代币00 00: 00:1 00:19等......

试试这个:

curl -XPUT http://localhost:9200/ap-test  -d '
{
    "settings" : {
        "analysis" : {
            "analyzer" : {
                "my_edge_ngram_analyzer" : {
                    "tokenizer" : "my_edge_ngram_tokenizer"
                }
            },
            "tokenizer" : {
                "my_edge_ngram_tokenizer" : {
                    "type" : "edgeNGram",
                    "min_gram" : "2",
                    "max_gram" : "17"
                }
            }
        }
    }
}'

curl -XPUT http://localhost:9200/ap-test/devices/_mapping  -d '
{
    "devices": {
        "properties" {
            "user": {
                "type": "string"
            },
            "macaddr": {
                "type": "string",
                "index_analyzer" : "my_edge_ngram_analyzer",
                "search_analyzer": "keyword"
            }
        }
    }
}'

像以前一样放置文档,然后使用专门针对该字段的查询进行搜索

curl -XPOST http://localhost:9200/ap-test/devices/_search -d '
{
    "query" : {
        "query_string" : {
            "query":"\"00\\:19\\:92\\:00\\:71\\:80\"",
            "fields": ["macaddr", "user"]
        }
    }
}'

关于您的上一个问题,不推荐使用text查询。

祝你好运!

答案 1 :(得分:2)

经过一些研究后,我找到了更简单的方法使其发挥作用。

Elasticsearch查询选项有时会让人感到困惑,因为它们有很多选项......

  • query_string:有一个完整的搜索,有无数的选项和 通配符使用。
  • match:更简单,不需要通配符 字符或其他“高级”功能。这个很好用 它在搜索框中,因为它失败的可能性非常小,如果不存在的话。

所以,那就是说。在大多数情况下,这是最好的,并且不需要自定义映射。

curl -XPOST http://localhost:9200/ap-test/devices/_search -d '
{
    "query" : {
        "match_phrase_prefix" : {
            "_all" : "00:19:92:00:71:8"
        }
    }
}'