es使用term+filter查詢(對type為text的查詢注意點)


插入測試數據

PUT /forum/article/_bulk
{ "index": { "_id": 1 }}
{ "articleID" : "XHDK-A-1293-#fJ3", "userID" : 1, "hidden": false, "postDate": "2017-01-01" }
{ "index": { "_id": 2 }}
{ "articleID" : "KDKE-B-9947-#kL5", "userID" : 1, "hidden": false, "postDate": "2017-01-02" }
{ "index": { "_id": 3 }}
{ "articleID" : "JODL-X-1937-#pV7", "userID" : 2, "hidden": false, "postDate": "2017-01-01" }
{ "index": { "_id": 4 }}
{ "articleID" : "QQPX-R-3956-#aD8", "userID" : 2, "hidden": true, "postDate": "2017-01-02" }

查看生成的mapping:

GET /forum/_mapping/article

結果(articleID除了顯示type外,還有一個fields顯示):

type=text,默認會設置兩個field,一個是field本身,比如articleID就是分詞的;還有一個就是field.keyword(這里是articleID.keyword),這個字段默認是不分詞的,並且最多保留256字符
{
  "forum": {
    "mappings": {
      "article": {
        "properties": {
          "articleID": {
            "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } }
          },
          "hidden": {
            "type": "boolean"
          },
          "postDate": {
            "type": "date"
          },
          "userID": {
            "type": "long"
          }
        }
      }
    }
  }
}

查詢id為2的精確匹配

GET /forum/article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "userID": "1"
        }
      },
      "boost": 1.2
    }
  }
}

constant_score:返回確切的得分

query+constant_score+filter+term:查找

term和terms的區別:terms是term的復數形式,用法 "terms": {"userID": ["1","2"]},term精確匹配一個,而terms是精確匹配多個值。

 

查詢articleID

GET /forum/article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "articleID":"XHDK-A-1293-#fJ3"
        }
      },
      "boost": 1.2
    }
  }
}

引用語句:結果為空。因為articleID.keyword,是ES最新版本內置建立的field,就是不分詞的。所以一個articleID過來的時候,會建立兩次索引。一次是自己本身(articleID),是要分詞的,分詞后放入倒排索引;另一次是基於articleID.keyword,不分詞,最多保留256字符,直接一個完整的字符串放入倒排索引中。

所以term filter,對text過濾,可以考慮使用內置的field.keyword來進行匹配。但是有個問題,默認就保留256字符,所以盡可能還是自己去手動建立索引,指定not_analyzed吧,在最新版本的es中,不需要指定not_analyzed也可以,將type=keyword即可。

自己的理解:term是精確查找,去找XHDK-A-1293-#fJ3

                    問題是創建索引的時候,默認對text進行分詞后簡歷索引。所以查詢不到。

                    但是keyword是未被分詞后索引,索引這種查找能查詢出來。

解決方法:

GET /forum/article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "articleID.keyword":"XHDK-A-1293-#fJ3"
        }
      },
      "boost": 1.2
    }
  }
}

 

更深度的理解,分詞后的索引:

GET /forum/_analyze
{
  "field": "articleID",
  "text": "XHDK-A-1293-#fJ3"
}

結果:

{
  "tokens": [
    {
      "token": "xhdk",
      "start_offset": 0,
      "end_offset": 4,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "a",
      "start_offset": 5,
      "end_offset": 6,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "1293",
      "start_offset": 7,
      "end_offset": 11,
      "type": "<NUM>",
      "position": 2
    },
    {
      "token": "fj3",
      "start_offset": 13,
      "end_offset": 16,
      "type": "<ALPHANUM>",
      "position": 3
    }
  ]
}

 

多條件查詢一:select * from forum.article where (post_date='2017-01-01' or article_id='XHDK-A-1293-#fJ3') and post_date!='2017-01-02'

GET /forum/article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
          "should" : [
            {"term" : {"postDate" : "2017-01-01"}},
            {"term" : {"articleID.keyword" : "XHDK-A-1293-#fJ3"}}
          ],
          "must_not" : {
            "term" : {"postDate" : "2017-01-02"}
          }
        }
      }
    }
  }
}

多條件查詢二:select * from forum.article where article_id='XHDK-A-1293-#fJ3' or (article_id='JODL-X-1937-#pV7' and post_date='2017-01-01')

GET /forum/article/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
          "should" : [
            {
              "term" : {"articleID.keyword" : "XHDK-A-1293-#fJ3"}
            },
            {
              "bool" : {
                "must" : [
                  {"term" : {"articleID.keyword" : "JODL-X-1937-#pV7"}},
                  {"term" : {"postDate" : "2017-01-01"}}
                ]
              }
            }
          ]
        }   
      }
    }
  }
}

 

參考文獻:https://www.jianshu.com/p/e1430282378d


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM