【问题标题】:Understand the result of sort on nested field in elastic search了解弹性搜索中嵌套字段的排序结果
【发布时间】:2021-02-18 18:12:43
【问题描述】:

我正在阅读 ElasticSearch Definitive Guide,关于在弹性搜索中对嵌套字段进行排序。

我正在使用 Elastic Search 7.10.1

以下是创建索引和准备数据的代码。

  1. 创建索引并设置映射
    PUT /my_index
    {
      "mappings": {
        "properties": {
          "body": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "comments": {
            "type": "nested",
            "properties": {
              "age": {
                "type": "long"
              },
              "comment": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "date": {
                "type": "date"
              },
              "name": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "stars": {
                "type": "long"
              }
            }
          },
          "tags": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "title": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }



  1. 插入数据:
PUT /my_index/_doc/1
{
  "title": "Nest eggs",
  "body": "Making your money work...",
  "tags": [
    "cash",
    "shares"
  ],
  "comments": [
    {
      "name": "John Smith",
      "comment": "Great article",
      "age": 28,
      "stars": 4,
      "date": "2014-09-01"
    },
    {
      "name": "Alice White",
      "comment": "More like this please",
      "age": 31,
      "stars": 5,
      "date": "2014-10-22"
    }
  ]
}

PUT /my_index/_doc/2
{
  "title": "Investment secrets",
  "body": "What they don't tell you ...",
  "tags": [
    "shares",
    "equities"
  ],
  "comments": [
    {
      "name": "Mary Brown",
      "comment": "Lies, lies, lies",
      "age": 42,
      "stars": 1,
      "date": "2014-10-18"
    },
    {
      "name": "John Smith",
      "comment": "You're making it up!",
      "age": 28,
      "stars": 2,
      "date": "2014-10-16"
    }
  ]
}

  1. 根据comments.starts 字段查询和排序
GET /my_index/_search
{
  "query": {
    "nested": {
      "path": "comments",
      "query": {
        "range": {
          "comments.date": {
            "gte": "2014-10-01",
            "lt": "2014-11-01"
          }
        }
      }
    }
  },
  "sort": {
    "comments.stars": {
      "order": "asc",
      "mode": "min",
      "nested_filter": {
        "range": {
          "comments.date": {
            "gte": "2014-10-01",
            "lt": "2014-11-01"
          }
        }
      }
    }
  }
}
  1. 结果如下:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : null,
        "_source" : {
          "title" : "Nest eggs",
          "body" : "Making your money work...",
          "tags" : [
            "cash",
            "shares"
          ],
          "comments" : [
            {
              "name" : "John Smith",
              "comment" : "Great article",
              "age" : 28,
              "stars" : 4,
              "date" : "2014-09-01"
            },
            {
              "name" : "Alice White",
              "comment" : "More like this please",
              "age" : 31,
              "stars" : 5,
              "date" : "2014-10-22"
            }
          ]
        },
        "sort" : [
          9223372036854775807
        ]
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : null,
        "_source" : {
          "title" : "Investment secrets",
          "body" : "What they don't tell you ...",
          "tags" : [
            "shares",
            "equities"
          ],
          "comments" : [
            {
              "name" : "Mary Brown",
              "comment" : "Lies, lies, lies",
              "age" : 42,
              "stars" : 1,
              "date" : "2014-10-18"
            },
            {
              "name" : "John Smith",
              "comment" : "You're making it up!",
              "age" : 28,
              "stars" : 2,
              "date" : "2014-10-16"
            }
          ]
        },
        "sort" : [
          9223372036854775807
        ]
      }
    ]
  }
}

我不明白结果,我无法弄清楚starts 是如何排序的。如果指定了"order":"asc" 和"order": "desc",,则没有区别

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    您需要修改排序查询,如下所示。参考这个官方文档,了解更多关于nested sorting的信息。

    在下面的排序查询中,首先根据范围查询过滤文档,然后按asc 或desc 的顺序对comments.stars 值进行排序。

    mode 用于决定在一个字段有多个comments.stars 值的情况下要做什么。例如,在您的情况下,在给定范围内,comments 下有两个文档具有 stars 值 1 和 2。当模式设置为 min 时,考虑stars 值1。

         {
      "query": {
        "nested": {
          "path": "comments",
          "query": {
            "range": {
              "comments.date": {
                "gte": "2014-10-01",
                "lt": "2014-11-01"
              }
            }
          },
          "inner_hits": {}
        }
      },
      "sort": [
        {
          "comments.stars": {
            "order": "asc",
            "mode": "min",
            "nested": {
              "path": "comments",
              "filter": { // note this
                "range": {
                  "comments.date": {
                    "gte": "2014-10-01",
                    "lt": "2014-11-01"
                  }
                }
              }
            }
          }
        }
      ]
    }
    

    搜索结果将是

    "hits": [
          {
            "_index": "66254927",
            "_type": "_doc",
            "_id": "6ZHts3cBlRfCLR0mFU3F",
            "_score": null,
            "_source": {
              "title": "Investment secrets",
              "body": "What they don't tell you ...",
              "tags": [
                "shares",
                "equities"
              ],
              "comments": [
                {
                  "name": "Mary Brown",
                  "comment": "Lies, lies, lies",
                  "age": 42,
                  "stars": 1,
                  "date": "2014-10-18"
                },
                {
                  "name": "John Smith",
                  "comment": "You're making it up!",
                  "age": 28,
                  "stars": 2,
                  "date": "2014-10-16"
                }
              ]
            },
            "sort": [
              1
            ],
            "inner_hits": {
              "comments": {
                "hits": {
                  "total": {
                    "value": 2,
                    "relation": "eq"
                  },
                  "max_score": 1.0,
                  "hits": [
                    {
                      "_index": "66254927",
                      "_type": "_doc",
                      "_id": "6ZHts3cBlRfCLR0mFU3F",
                      "_nested": {
                        "field": "comments",
                        "offset": 0
                      },
                      "_score": 1.0,
                      "_source": {
                        "name": "Mary Brown",
                        "comment": "Lies, lies, lies",
                        "age": 42,
                        "stars": 1,
                        "date": "2014-10-18"            // note this
                      }
                    },
                    {
                      "_index": "66254927",
                      "_type": "_doc",
                      "_id": "6ZHts3cBlRfCLR0mFU3F",
                      "_nested": {
                        "field": "comments",
                        "offset": 1
                      },
                      "_score": 1.0,
                      "_source": {
                        "name": "John Smith",
                        "comment": "You're making it up!",
                        "age": 28,
                        "stars": 2,
                        "date": "2014-10-16"               // note this
                      }
                    }
                  ]
                }
              }
            }
          },
          {
            "_index": "66254927",
            "_type": "_doc",
            "_id": "1",
            "_score": null,
            "_source": {
              "title": "Nest eggs",
              "body": "Making your money work...",
              "tags": [
                "cash",
                "shares"
              ],
              "comments": [
                {
                  "name": "John Smith",
                  "comment": "Great article",
                  "age": 28,
                  "stars": 4,
                  "date": "2014-09-01"
                },
                {
                  "name": "Alice White",
                  "comment": "More like this please",
                  "age": 31,
                  "stars": 5,
                  "date": "2014-10-22"
                }
              ]
            },
            "sort": [
              5
            ],
            "inner_hits": {
              "comments": {
                "hits": {
                  "total": {
                    "value": 1,
                    "relation": "eq"
                  },
                  "max_score": 1.0,
                  "hits": [
                    {
                      "_index": "66254927",
                      "_type": "_doc",
                      "_id": "1",
                      "_nested": {
                        "field": "comments",
                        "offset": 1
                      },
                      "_score": 1.0,
                      "_source": {
                        "name": "Alice White",
                        "comment": "More like this please",
                        "age": 31,
                        "stars": 5,
                        "date": "2014-10-22"          // note this
                      }
                    }
                  ]
                }
              }
            }
          }
        ]
    

    【讨论】:

    • 感谢@escoder。我修改了查询并关注您的查询。查询结果还有一个问题。正如您所粘贴的:为什么``“date”:“2014-09-01”``也包含在cmets中?我已将评论过滤为 2014-10-01 ~ 2014-10-31
    • @Tom 您可以使用inner_hits 仅获取范围内的那些文档。请查看更新后的查询,如果这能解决您的问题,请告诉我?
    • 好的,谢谢@escoder,明白了,谢谢!
    猜你喜欢
    • 2016-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    • 2014-10-28
    • 2021-01-21
    • 1970-01-01
    • 2015-09-18
    相关资源
    最近更新 更多