【问题标题】:ElasticSearch Searching for same value on list fields with same nameElasticSearch在具有相同名称的列表字段上搜索相同的值
【发布时间】:2016-03-07 15:40:33
【问题描述】:

在具有相同名称的字段上搜索相同的值。仅当所有值都属于字段“list.perInd”为“IXSO”时,我才希望在文档下方返回..... 原始文档是这样的

        {
           "pkClmn": 676101388023,
           "dutyCde": "RICE",
           "list": [
              {
                 "pkClmn": 67610138804,
                 "perInd": "IXSO",
              },
              {
                 "pkClmn": 67610138803,
                 "perInd": "IXSO",
              },
              {
                 "pkClmn": 67610138802,
                 "perInd": "IASI",
              },
              {
                 "pkClmn": 67610138801,
                 "perInd": "IASI",
              }
           ]
        }

仅当 list.perInd 包含所有 4 个 IXSO 时才返回 doc ...

【问题讨论】:

  • 您能否为您的问题添加更多解释??
  • 好吧,我删除了我的答案,因为我认为我弄错了,你能解释一下你想要搜索什么以及应该返回什么吗?
  • 或者您的意思是仅当 list.perInd 包含所有 4 个 IXSO 时您才想要返回文档?
  • 是的,仅当 list.perInd 包含所有 4 个 IXSO 时才返回 doc
  • 我已经为您的问题发布了可能的解决方案

标签: elasticsearch spring-data-elasticsearch


【解决方案1】:

当前的解决方案可能存在一些性能问题,但它可以工作,您应该对其进行测试

POST stack/type1/1
{
  "pkClmn": 676101388023,
  "dutyCde": "RICE",
  "list": [
    {
      "pkClmn": 67610138804,
      "perInd": "IXSO"
    },
    {
      "pkClmn": 67610138803,
      "perInd": "IXSO"
    },
    {
      "pkClmn": 67610138802,
      "perInd": "IASI"
    },
    {
      "pkClmn": 67610138801,
      "perInd": "IASI"
    }
  ]
} 


POST stack/type1/2
{
  "pkClmn": 676101388023,
  "dutyCde": "RICE",
  "list": [
    {
      "pkClmn": 67610138804,
      "perInd": "IXSO"
    },
    {
      "pkClmn": 67610138803,
      "perInd": "IXSO"
    },
    {
      "pkClmn": 67610138802,
      "perInd": "IXSO"
    },
    {
      "pkClmn": 67610138801,
      "perInd": "IXSO"
    }
  ]
} 


POST stack/type1/_search
{
  "query": {
    "filtered": {
      "query": {
        "term": {
          "list.perInd": {
            "value": "ixso"
          }
        }
      },
      "filter": {
        "script": {
          "script": "doc['list.perInd'].value == value",
          "params": {
            value: "ixso"
          }
        }
      }
    }
  }
}

让我解释一下它为什么起作用。 Elasticsearch 使用倒排索引来存储数据。

所以当你索引文档文本被标记时(同样有很多标记器可以是单词,也可以是几个单词。阅读 Elasticsearch 标记器),在标准标记中是一个单词。因此,在倒排索引中有术语和对我们示例中的文档的引用,它需要 ixsoiasi 并将它们写在倒排索引中。因此,如果您有两个术语,则 doc[fieldname].values 将具有这两个术语的数组,在我的情况下,我正在检查 .value 属性,因为它将被强制转换为字符串,并且如果有两个令牌字符串将不同于参数.

还有analyzed and not_analyzed 映射。在我的示例中,我展示了已分析的内容,它仅适用于一个术语 perInd。例如,如果您将索引“测试词”我的解决方案将不起作用,因为 doc['list.perInd'].values 将返回 ["ixso", "test"]。如果您使用多个单词,则必须使用 not_analyzed

如您所见,我还使用字符串参数让 elasticsearch 缓存我的过滤器以提高性能。

Image from

【讨论】:

  • 你能解释一下吗...我是弹性搜索的新手...脚本部分如何工作...在这里您正在检查 list.perInd == IXSO ,它如何检查所有值是否相同??
  • 是的,我也有同样的问题。比较如何确保数组中的所有值都相同?但神奇的是,您的代码有效。我测试了:)
  • 我使用相同的想法编写了另一个我认为很容易理解的查询,尽管我不知道它的性能问题。 {"filter":{"script":{"script":"for (value in doc['list.perInd'].values) { if (value != param) return false }; return true","params":{"param":"ixso"}}}}
  • @VinuDominic 是的,它也是可能的,性能与我的解决方案完全相同。
  • @user2526641 我已经在我的帖子中添加了解释,希望它有意义并且对你有帮助
【解决方案2】:

您在数据模型中需要注意一些事项。 首先你的列表是一个嵌套对象,你需要创建一个这样的映射

curl -XPUT "http://192.168.99.100:9200/testt" -d'
{
      "mappings": {
         "stack": {
            "properties": {
               "list": {
                  "type": "nested"

               }
            }
         }
   }
}'

现在让我们插入我们的示例数据

curl -XPOST "http://192.168.99.100:9200/testt/stack" -d'
{
           "pkClmn": 676101388023,
           "dutyCde": "RICE",
           "list": [
              {
                 "pkClmn": 67610138804,
                 "perInd": "IXSO"
              },
              {
                 "pkClmn": 67610138803,
                 "perInd": "IXSO"
              },
              {
                 "pkClmn": 67610138802,
                 "perInd": "IASI"
              },
              {
                 "pkClmn": 67610138801,
                 "perInd": "IASI"
              }
           ]
        }'

现在让我们搜索一下

curl -XPOST "http://192.168.99.100:9200/testt/stack/_search" -d'
{
    "query": {
       "nested": {
          "path": "list",
          "query": {
              "filtered": {
                 "filter": {
                     "term": {
                        "list.perInd": "ixso"
                     }
                 }
              }
          }
       }

    }
}'

我们将使用带有术语过滤器的嵌套查询,过滤器可以在您的情况下缓存,这是最佳选择。 希望对你有帮助,有问题可以问我。

【讨论】:

  • 感谢您的回答。嵌套对象的性能低于非规范化对象。这就是我们尽可能使用非规范化对象的原因。是否有可能在非规范化对象中实现相同的目标。
  • 嵌套对象比普通对象快,问题是你正在做的查询。请给我一个非规范化数据的例子。
  • 以上是非规范化的..我们没有将对象标记为嵌套类型..它是普通对象
  • 只是为了了解它将如何返回具有 ALL 4 ixso 的对象?正如我所见,如果他们中的任何一个有它或者我误解了smth,当前查询将过滤?
  • 这个答案如何解决OP的要求?即使list.perInd 没有全部 "IXSO",它也会返回文档。
猜你喜欢
  • 2015-02-15
  • 2021-11-22
  • 1970-01-01
  • 2016-08-25
  • 1970-01-01
  • 2022-01-09
  • 2017-03-03
  • 2014-07-17
  • 1970-01-01
相关资源
最近更新 更多