【问题标题】:Filter and sort based on attributes in Terms lookup document in Elastic Search根据 Elastic Search 中的术语查找文档中的属性进行过滤和排序
【发布时间】:2019-09-27 18:34:38
【问题描述】:

我的索引中有一些文档:

POST "/index/thing/_bulk" -s -d'
    { "index":{ "_id": 1 } }
    { "title":"One thing"}
    { "index":{ "_id": 2 } }
    { "title":"Second thing"}
    { "index":{ "_id": 3 } }
    { "title":"Three things"}
    { "index":{ "_id": 4 } }
    { "title":"And so fourth"}
    { "index":{ "_id": 5 } }
    { "title":"Five things"}
'

我还有包含用户collection 的文档,这些用户通过文档id 属性链接到其他文档(事物),如下所示:

PUT /index/collection/1
{
    "items": [
        {"id": 1, "time_added": "2017-08-07T09:07:15.000Z", "condition": "fair"},
        {"id": 3, "time_added": "2019-08-07T09:07:15.000Z", "condition": "good"},
        {"id": 4, "time_added": "2016-08-07T09:07:15.000Z", "condition": "poor"}
    ]
}

然后我使用terms lookup 来获取用户集合中的所有内容,如下所示:

GET /documents/_search
{
    "query" : {
        "terms" : {
            "_id" : {
                "index" : "index",
                "type" : "collection",
                "id" : 1,
                "path" : "items.id"
            }
        }
    }
}

这很好用。我得到了集合中的三个文档,并且可以根据需要搜索、排序和使用聚合。

但是有没有办法根据collection 文档中的属性(在本例中为time_addedcondition)来聚合、过滤和排序这些文档?假设我想根据time_added 进行排序或从集合中过滤condition=="good"

也许可以将脚本应用于collection 以对其中的项目进行排序或过滤?感觉这和left-join之类的sql已经很接近了,所以也许E​​lastic Search是错误的工具?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    看来您需要nested data type

    以你的数据为例:

    没有嵌套类型

    POST collection/_bulk?filter_path=_
    {"index":{}}
    {"items":[{"id":11,"time_added":"2017-08-07T09:07:15.000Z","condition":"fair"},{"id":13,"time_added":"2019-08-07T09:07:15.000Z","condition":"good"},{"id":14,"time_added":"2016-08-07T09:07:15.000Z","condition":"poor"}]}
    {"index":{}}
    {"items":[{"id":21,"time_added":"2017-09-07T09:07:15.000Z","condition":"fair"},{"id":23,"time_added":"2019-09-07T09:07:15.000Z","condition":"good"},{"id":24,"time_added":"2016-09-07T09:07:15.000Z","condition":"poor"}]}
    {"index":{}}
    {"items":[{"id":31,"time_added":"2017-10-07T09:07:15.000Z","condition":"fair"},{"id":33,"time_added":"2019-10-07T09:07:15.000Z","condition":"good"},{"id":34,"time_added":"2016-10-07T09:07:15.000Z","condition":"poor"}]}
    {"index":{}}
    {"items":[{"id":41,"time_added":"2017-11-07T09:07:15.000Z","condition":"fair"},{"id":43,"time_added":"2019-11-07T09:07:15.000Z","condition":"good"},{"id":44,"time_added":"2016-11-07T09:07:15.000Z","condition":"poor"}]}
    {"index":{}}
    {"items":[{"id":51,"time_added":"2017-12-07T09:07:15.000Z","condition":"fair"},{"id":53,"time_added":"2019-12-07T09:07:15.000Z","condition":"good"},{"id":54,"time_added":"2016-12-07T09:07:15.000Z","condition":"poor"}]}
    

    查询(你会得到不正确的结果 - 预期一个,得到五个):

    GET collection/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "items.condition": {
                  "value": "good"
                }
              }
            },
            {
              "range": {
                "items.time_added": {
                  "lte": "2019-09-01"
                }
              }
            }
          ]
        }
      }
    }
    

    聚合(不正确的结果 - 查看第一个存储桶 "2016-08-01T00:00:00.000Z" - 它包含每个条件类型的 3 个 CONDITION 子存储桶)

    GET collection/_search
    {
      "size": 0,
      "aggs": {
        "DATE": {
          "date_histogram": {
            "field": "items.time_added",
            "calendar_interval": "month"
          },
          "aggs": {
            "CONDITION": {
              "terms": {
                "field": "items.condition.keyword",
                "size": 10
              }
            }
          }
        }
      }
    }
    

    有嵌套类型

    DELETE collection
    
    PUT collection
    {
      "mappings": {
        "properties": {
          "items": {
            "type": "nested"
          }
        }
      }
    }
    
    # and POST the same data from above
    

    查询(只返回一个结果)

    GET collection/_search
    {
      "query": {
        "nested": {
          "path": "items",
          "query": {
            "bool": {
              "must": [
                {
                  "term": {
                    "items.condition": {
                      "value": "good"
                    }
                  }
                },
                {
                  "range": {
                    "items.time_added": {
                      "lte": "2019-09-01"
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
    

    聚合(第一个日期桶只包含一个CONDITION 子桶)

    GET collection/_search
    {
      "size": 0,
      "aggs": {
        "ITEMS": {
          "nested": {
            "path": "items"
          },
          "aggs": {
            "DATE": {
              "date_histogram": {
                "field": "items.time_added",
                "calendar_interval": "month"
              },
              "aggs": {
                "CONDITION": {
                  "terms": {
                    "field": "items.condition.keyword",
                    "size": 10
                  }
                }
              }
            }
          }
        }
      }
    }
    

    希望有帮助:)

    【讨论】:

    • 你能详细说明一下吗?我想我必须将集合数组索引为嵌套,但我将如何根据它们进行查询?
    • ES guides 很好地描述了它。我根据您上面的数据添加了一个示例。
    • 感谢@jetnet 的详细说明。恐怕它不能完全回答我的问题,我想可能还不够清楚,我已经添加了更多细节。我不想搜索集合,而是使用它来过滤其他文档,并想知道我是否可以这样做并且仍然使用属性 from 进行排序或过滤。
    猜你喜欢
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多