当前位置: 首页 > 知识库问答 >
问题:

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

庄嘉
2023-03-14

我确实在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个答案

公羊曜灿
2023-03-14

我最近在ElasticSearch中找到了以下文档:https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_multiple_exact_values.html

TermQuery和TermsQuery或ElasticSearch通常使用“must contain”而不是“must equals to”,因为它的索引是倒排的。

他们认为,可能的最佳解决办法是:

如果您确实想要这种行为--整个字段相等--实现它的最佳方法包括索引一个次要字段。在此字段中,索引字段包含的值数。利用我们以前的两份文件。一旦索引了计数信息,就可以构造一个constant_score来执行适当数量的术语。https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_multiple_exact_values.html#_equals_actical

以下步骤:

  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
}

在Java中,

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);
 类似资料:
  • 问题内容: 我有一个类似以下设置和映射的索引; 我正在努力实现现场通配符搜索的实现。我的示例数据如下: 当我执行以下查询时; 它返回,。我认为,它仍然标记数据。它只能返回。 您能帮上忙吗? 提前致谢 问题答案: 我的解决方案历险记 如您在我的问题中所见,我已经开始审理案件。每当我更改了一部分设置后,一部分便开始工作,而另一部分则停止工作。让我给出我的解决方案历史记录: 1.) 我已将数据索引为默认

  • 问题内容: 我对ES还是相当陌生,并正在将其用于我的新项目。首先,我为客户提供了一个简单的映射,其中包含名字和姓氏以及付款信息对象列表。如果我在SQL中执行此操作,那将类似于客户表和具有1:许多关系的付款信息表。 这是我要执行的操作的一个简单示例:https : //gist.github.com/anonymous/6109593 我希望根据payInfos嵌套数组中的任何匹配项找到任何客户,即

  • 我有一个endpoint,我正在将它代理到ElasticSearchAPI中,以进行简单的用户搜索。 有关这些参数的一些详细信息如下 所有参数都是可选的 昵称可以作为全文搜索进行搜索(即'myUser'将返回'myUsername') 电子邮件必须完全匹配 名称可以搜索为每个令牌的全文搜索(即'john'将返回'John Smith') ElasticSearch调用应将参数集体视为AND'd。

  • 问题内容: 我正在对具有字符串类型数组的文档字段进行自动完成建议。我的文件如下所示; 我正在 标签 字段上执行自动完成搜索。我的查询就像; 当用户键入“ word”时,我要显示“ wordland”和“ wordpress”。但是,我无法做到这一点。 您能帮上忙吗? 谢谢 问题答案: 您是否尝试过完成建议?解决问题的一种方法如下: 1)创建索引: 2)使用完成建议者类型创建映射: 3)添加文件:

  • 我有一个要求,以提供功能,将允许用户搜索通过许多不同的领域元素,并看到结果作为组合列表。所以在UI中,他只需要填充一个文本字段,然后检索结果。 为了可视化,假设我在域中有3个实体: 现在我想我可以达到这样的要求: 但是当调用第二个函数--负责返回实际文档的函数时,会引发以下异常: 无法标识索引名称。GlobalSearchDTO不是文档。确保document类被@document(indexnam

  • 问题内容: 在哪里可以找到有关WDS的文档,特别是使用C#中的SQL查询来查询WDS?是否有任何资源列出可以从SystemIndex查询的列?另外,我希望查询返回“上下文”,即就像WDS客户端从找到搜索词的文档中的几行开始一样。尽管我相信3+的API是相同的,但我正在使用WDS 4.0。我检查了MSDN和其他站点,但是没有运气。 问题答案: 在MSDN论坛上发布并得到答案:可以搜索的列或属性:ht