亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

ElasticSearch 通過數組字段搜索作為獨占搜索

ElasticSearch 通過數組字段搜索作為獨占搜索

qq_笑_17 2023-03-09 14:02:47
我在 ElasticSearch 的字段中確實有一個關鍵字類型的數據數組。我想用我想搜索的獨占值搜索這個數組,即排除不包含在我的搜索關鍵字中的數組值。請參閱下面的詳細信息。謝謝!我有以下彈性搜索索引映射:"exgroups": {  "type": "keyword",  "eager_global_ordinals": true},使用以下示例數據:"id": 1,"exgroups": ["TSX"]"id": 2,"exgroups": ["TSX", "OTC", "NSD"]我的搜索是這樣的:{  "bool" : {    "filter" : {        "term" : {          "exgroups" : {            "value" : "TSX"          }        }    }  }}我用過 MatchQueryBuilder、TermQueryBuilder、TermsQueryBuilder 都無濟于事。根據 ElasticSearch TermQuery 的定義,它應該可以解決問題。https://www.elastic.co/guide/en/elasticsearch/reference/6.2/query-dsl-term-query.html。但它沒有,可能是因為該字段是一個數組。通常,Term*Query 的行為如下:iterate all the documents, for each document  check if the exgroups contains 'tsx'  if it does, return the document這將返回文檔 1 和 2,因為文檔 2 也包含 TSX。但是,我希望它只返回文檔 1,而不返回數組中的其他文檔。我該如何做到這一點?
查看完整描述

1 回答

?
慕容3067478

TA貢獻1773條經驗 獲得超3個贊

重新索引解決方案:

我最近從 ElasticSearch 找到了這個文檔: https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_multiple_exact_values.html

由于倒排索引,TermQuery 和 TermsQuery 或 ElasticSearch 通常都使用“必須包含”而不是“必須等于”。

根據他們的說法,最好的解決方案是:

如果您確實想要這種行為——整個字段相等——實現它的最好方法是索引一個輔助字段。在此字段中,您索引字段包含的值的數量。使用我們之前的兩個文檔。將計數信息編入索引后,您可以構建一個 constant_score 來強制執行適當數量的術語。https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_multiple_exact_values.html#_equals_exactly

步驟如下:

  1. 在名為 exgroups_count 的索引中添加額外的映射。

  2. 使用 logstash 計算 exgroups 數組長度并放入 exgroups_count 字段。

  3. 保存索引。

沒有重新索引的另一個解決方案:

添加和重新索引整個事物有一些限制。一旦您的索引增長,向索引添加字段和計算計數將是非常具有侵入性的 - 使其操作非常密集 - 更不用說您必須保存和維護您的映射。

我找到了一個不需要重新索引的解決方案。查看 ScriptQueryBuilder,理論上我可以添加一個腳本過濾器來計算數組的長度并等于 1。

"filter" : {

    "script" : {

        "script" : "doc['exgroups'].values.length == 1"

    }

}

所以完整的查詢現在變成這樣:


"bool" : {

  "must" : [

    {

      "term" : {

        "exgroups" : {

          "value" : "TSX",

          "boost" : 1.0

        }

      }

    }

  ],

  "filter" : [

    {

      "script" : {

        "script" : {

          "source" : "doc['exgroups'].values.length == 1",

          "lang" : "painless"

        },

        "boost" : 1.0

      }

    }

  ],

  "adjust_pure_negative" : true,

  "boost" : 1.0

}

在爪哇,


BoolQueryBuilder qBool = new BoolQueryBuilder();

TermQueryBuilder query = new TermQueryBuilder("exgroups", exchangeGroup.getCode());


qBool.must(query);


ScriptQueryBuilder sQuery = new ScriptQueryBuilder(new Script("doc['exgroups'].values.length == 1"));


qBool.filter(sQuery);


查看完整回答
反對 回復 2023-03-09
  • 1 回答
  • 0 關注
  • 208 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號