【问题标题】:Filter ElasticSearch results based on AND condition in an array根据数组中的 AND 条件过滤 ElasticSearch 结果
【发布时间】:2020-08-19 04:59:40
【问题描述】:

以下是我的索引中单个记录的数据样本:

{
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "49605102905391763685971719283371021096086998966740189186",
        "_score" : 2.8858113,
        "_source" : {
          "properties" : {
            "activity" : [
              {
                "activityId" : 39,
                "actionVersion" : 2,
                "actionIdx" : 3
              },
              {
                "activityId" : 39,
                "actionVersion" : 2,
                "actionIdx" : 4
              },
              {
                "activityId" : 39,
                "actionVersion" : 2,
                "actionIdx" : 5
              },
              {
                "activityId" : 42,
                "actionVersion" : 2,
                "actionIdx" : 3
              },
              {
                "activityId" : 42,
                "actionVersion" : 2,
                "actionIdx" : 4
              },
              {
                "activityId" : 42,
                "actionVersion" : 2,
                "actionIdx" : 5
              }
            ]
          }
        }
      }

我想根据 activitiyId 42 和 actionIdx 3 过滤结果。我正在使用下面的查询来获取结果。

{"size":-1,
  "query": {
    "bool": {
            "should": {
                "bool": {
                    "must": [
                        {
                            "match": {
                                "activityId": 42
                            }
                        },
                        {
                            "match": {
                                "actionIdx": 3
                            }
                        }
                        
                        
                    ]
                }
            }
        }
  }
}

我正在获取包含 activityid 42 和 actionidx 3 的记录,但我的要求是在同一个对象中包含包含 activity 42 和 actionidx 3 的记录。以下是我使用上述搜索查询的结果:

      "activity" : [
              {
                "activityId" : 39,
                "actionVersion" : 2,
                "actionIdx" : 2
              },
              {
                "activityId" : 28,
                "actionVersion" : 2,
                "actionIdx" : 3
              },
              {
                "activityId" : 42,
                "actionVersion" : 2,
                "actionIdx" : 2
              },
              {
                "activityId" : 41,
                "actionVersion" : 2,
                "actionIdx" : 3
              }
            ]

我的预期输出是:

"activity" : [
              {
                "activityId" : 39,
                "actionVersion" : 2,
                "actionIdx" : 2
              },
              {
                "activityId" : 28,
                "actionVersion" : 2,
                "actionIdx" : 3
              },
              {
                "activityId" : 42,
                "actionVersion" : 2,
                "actionIdx" : 3
              }
            ]

这是映射索引。 Activity 没有嵌套

"properties" : {
            "properties" : {
              "activity" : {
                "properties" : {
                  "actionIdx" : {
                    "type" : "long"
                  },
                  "actionVersion" : {
                    "type" : "long"
                  },
                  "activityId" : {
                    "type" : "long"
                  }
                }
              }
            }
          }

【问题讨论】:

  • 你能提供你的索引映射吗?我正在处理您的搜索查询,并将提供一个工作示例
  • 嗨@OpsterElasticsearchNinja,我尝试使用嵌套类型对象创建一个新索引,但我仍然面临没有得到结果的问题。
  • 我已经给出了嵌套类型的完整示例,你试过了吗?

标签: database elasticsearch elastic-stack


【解决方案1】:

您需要使用nested data type 和查询来实现这一点,因为您现在没有使用它,它被视为对象数据类型(默认)并且嵌套文档清楚地提到了您面临的问题。

当摄取具有大量任意键的键值对时, 您可以考虑将每个键值对建模为自己的嵌套 具有键和值字段的文档。相反,请考虑使用 扁平化数据类型,将整个对象映射为单个字段,并且 允许对其内容进行简单搜索。嵌套文档和 查询通常很昂贵,因此使用扁平数据类型 这个用例是更好的选择。

索引映射

    {
  "mappings": {
    "properties": {
      "properties": {
        "properties": {
          "activity": {
            "type": "nested"
          }
        }
      }
    }
  }
}

索引数据:

{
    "properties": {
        "activity": [
            {
                "activityId": 39,
                "actionVersion": 2,
                "actionIdx": 3
            },
            {
                "activityId": 39,
                "actionVersion": 2,
                "actionIdx": 4
            },
            {
                "activityId": 39,
                "actionVersion": 2,
                "actionIdx": 5
            },
            {
                "activityId": 42,
                "actionVersion": 2,
                "actionIdx": 3
            },
            {
                "activityId": 42,
                "actionVersion": 2,
                "actionIdx": 4
            },
            {
                "activityId": 42,
                "actionVersion": 2,
                "actionIdx": 5
            }
        ]
    }
}

搜索查询:

{
  "query": {
    "nested": {
      "path": "properties.activity",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "properties.activity.activityId": 42
              }
            },
            {
              "match": {
                "properties.activity.actionIdx": 3
              }
            }
          ]
        }
      },
      "inner_hits":{}
    }
  }
}

搜索结果

 "hits": [
                {
                  "_index": "fd_cb1",
                  "_type": "_doc",
                  "_id": "1",
                  "_nested": {
                    "field": "properties.activity",
                    "offset": 3
                  },
                  "_score": 2.0,
                  "_source": {
                    "activityId": 42,
                    "actionVersion": 2,
                    "actionIdx": 3
                  }
                }
              ]

【讨论】:

  • 您好,我已尝试查询,但仍无法正常工作。活动的映射也不是嵌套的。
猜你喜欢
  • 2019-10-26
  • 2022-01-23
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-12
  • 2016-02-17
相关资源
最近更新 更多