ElasticSearch 通过数组字段搜索作为独占搜索

我在 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,而不返回数组中的其他文档。


我该如何做到这一点?


qq_笑_17
浏览 296回答 1
1回答

慕容3067478

重新索引解决方案:我最近从 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步骤如下:在名为 exgroups_count 的索引中添加额外的映射。使用 logstash 计算 exgroups 数组长度并放入 exgroups_count 字段。保存索引。没有重新索引的另一个解决方案:添加和重新索引整个事物有一些限制。一旦您的索引增长,向索引添加字段和计算计数将是非常具有侵入性的 - 使其操作非常密集 - 更不用说您必须保存和维护您的映射。我找到了一个不需要重新索引的解决方案。查看 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);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java