代码之家  ›  专栏  ›  技术社区  ›  Sagar Chilukuri

ElasticSearch 5.6中的MySql按值排序等效项

  •  1
  • Sagar Chilukuri  · 技术社区  · 7 年前

    ElasticSearch版本:5.6

    我在ElasticSearch中导入了MySQL数据,并根据需要向ElasticSearch添加了映射。下面是该列的一个映射 application_status .

    映射:

    {
    "settings": {
        "analysis": {
            "analyzer": {
                "case_insensitive": {
                    "type": "custom",
                    "tokenizer": "keyword",
                    "filter": ["lowercase"]
                }
            }
        }
    },
    "mappings": {
        "lead": {
            "properties": {
                "application_status": {
                    "type": "string",
                    "analyzer": "case_insensitive",
                    "fields": {
                        "keyword": {
                            "type": "keyword"
                        }
                    }
                }
            }
        }
    }}
    

    在上面的映射中,我能够进行简单的排序( asc desc )使用以下查询:

    {
    "size": 50,
    "from": 0,
    "sort": [{
        "application_status.keyword": {
            "order": "asc"
        }
    }]}
    

    MySql等价于

    select * from <table_name> order by application_status asc limit 50;
    

    需要以下问题的帮助: 我有MySQL查询,它根据 应用程序状态 :

    select * from vLoan_application_grid order by CASE WHEN application_status = "IP_QUAL_REASSI" THEN application_status END desc, CASE WHEN application_status = "IP_COMPLE" THEN application_status END desc, CASE WHEN application_status LIKE "IP_FRESH%" THEN application_status END desc, CASE WHEN application_status LIKE "IP_%" THEN application_status END desc
    

    请帮助我在ElasticSearch中编写相同的查询。我找不到 order by value 等效于 strings 在ElasticSearch中。在网上搜索,我明白,我应该使用 sorting scripts

    我有下面的查询,它只做简单的排序。

    {
    "size": 500,
    "from": 0,
    "query" : {
        "match_all": {}
    },
    "sort": {
        "_script": {
            "type": "string",
            "script": {
                "source": "doc['application_status.keyword'].value",
                "params": {
                    "factor": ["IP_QUAL_REASS", "IP_COMPLE"]
                }
            },
            "order": "desc"
        }
    }}
    

    在上述查询中,我没有使用 params 部分,因为我不知道如何使用它 type: string

    我想我要求的太多了。请提供帮助或任何相关文档链接,我们将不胜感激。希望问题很清楚。如有必要,我会提供更多细节。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Andrei Stefan    7 年前

    您有两种选择:

    • 最有效的方法是在索引时索引另一个应该是数字的字段。这个数字(您的选择)将是该状态的数字表示。然后在搜索时,您只需按该数字排序,而不是按状态排序
    • 在搜索时,使用一个脚本,该脚本将执行与第一个选项几乎相同的操作,但具有动态性,性能较低(但仍然相当快)

    下面是第二个选项:

      "sort": {
        "_script": {
          "type": "number",
          "script": {
            "source": "if (params.factor[0].containsKey(doc['application_status.keyword'].value)) return params.factor[0].get(doc['application_status.keyword'].value); else return 1000;",
            "params": {
              "factor": [{
                "IP_QUAL_REASS":1,
                "IP_COMPLE":2,
                "whatever":3
              }
              ]
            }
          },
          "order": "asc"
        }
      }
    

    如果你也想要这样的东西 LIKE WHATEVER% ,我的建议是考虑索引时间的更改,而不是搜索时间,因为脚本变得更复杂。但是,这也是用于通配符匹配的:

      "sort": {
        "_script": {
          "type": "number",
          "script": {
            "source": "if (params.factor[0].containsKey(doc['application_status.keyword'].value)) return params.factor[0].get(doc['application_status.keyword'].value); else { params.wildcard_factors[0].entrySet().stream().filter(kv -> doc['application_status.keyword'].value.startsWith(kv.getKey())).map(Map.Entry::getValue).findFirst().orElse(1000)}",
            "params": {
              "factor": [
                {
                  "IP_QUAL_REASS": 1,
                  "IP_COMPLE": 2,
                  "whatever": 3
                }
              ],
              "wildcard_factors": [
                {
                  "REJ_": 66
                }
              ]
            }
          },
          "order": "asc"
        }
      }