ElasticSearch在具有相同名称的列表字段上搜索相同的值

时间:2016-03-07 15:40:33

标签: elasticsearch spring-data-elasticsearch

在具有相同名称的字段上搜索相同的值。我只想在所有值都是字段" list.perInd"是&IXSOX' ..... 原始Doc看起来像这样

        {
           "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

2 个答案:

答案 0 :(得分:0)

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

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使用反向索引来存储数据。 Inverted index

所以当你索引文档文本被标记化时(再次有许多标记符可以是单词,可以是几个单词。阅读关于Elasticsearch标记化器),在标准标记中是一个单词。因此,在倒排索引中,对于来自我们的示例的文档有术语和参考,它需要 ixso iasi 并将它们写入倒排索引。所以,如果你有两个术语,那么doc [fieldname] .values将有两个术语的数组,在我的情况下,我正在检查.value属性,因为它将被转换为字符串,如果有两个令牌字符串将不同于参数

还有analyzed and not_analyzed映射。在我的例子中,我用分析显示,它只适用于一个术语 perInd 。例如,如果您将索引“测试词”,我的解决方案将无效,因为 doc ['list.perInd']。值将返回 [“ixso”,“test”] 。如果您使用多个单词,则必须使用not_analyzed

如你所见,我也在使用字符串参数让elasticsearch缓存我的过滤器以提升性能。

Image from

答案 1 :(得分:-1)

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

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"
                     }
                 }
              }
          }
       }

    }
}'

我们将使用带有术语过滤器的嵌套查询,在您的情况下可以缓存过滤器,它是最佳选择。 我希望它有所帮助,如果有疑问,请问我。