首页 > 解决方案 > 根据用户输入的值在弹性搜索中排序

问题描述

我想按用户输入的顺序获取产品。假设如果用户搜索“Z1234”、“S1234”、“T2344”,那么我想要按特定顺序排列的产品。其中 Z1234 将是第一条记录。如何在弹性搜索中实现这一点。我尝试过使用“脚本”和其他方式,但它不起作用。下面是我的脚本使用示例。

'_script' => [
            'script' => "for(i:scoring) { if(doc[\"custom_44\"].value == i.id) return i.score; } return 0;",
            "type" => "number",
            'params' => [
                'scoring' => [
                    ['id'=>'3MS01',"score" => 1],
                    ['id'=>'29xcs',"score" => 2],                  
                ]
            ],
            "order" => "asc"
        ]

我的工作查询正文如下

Array
(
[size] => 20
[from] => 0
[query] => Array
    (
        [filtered] => Array
            (
                [filter] => Array
                    (
                        [bool] => Array
                            (
                                [must] => Array
                                    (
                                        [0] => Array
                                            (
                                                [bool] => Array
                                                    (
                                                        [should] => Array
                                                            (
                                                                [0] => Array
                                                                    (
                                                                        [query] => Array
                                                                            (
                                                                                [span_near] => Array
                                                                                    (
                                                                                        [clauses] => Array
                                                                                            (
                                                                                                [0] => Array
                                                                                                    (
                                                                                                        [span_multi] => Array
                                                                                                            (
                                                                                                                [match] => Array
                                                                                                                    (
                                                                                                                        [regexp] => Array
                                                                                                                            (
                                                                                                                                [custom_44] => .*3MS01.*
                                                                                                                            )

                                                                                                                    )

                                                                                                            )

                                                                                                    )

                                                                                            )

                                                                                        [slop] => 0
                                                                                        [in_order] => 1
                                                                                    )

                                                                            )

                                                                    )

                                                                [1] => Array
                                                                    (
                                                                        [query] => Array
                                                                            (
                                                                                [span_near] => Array
                                                                                    (
                                                                                        [clauses] => Array
                                                                                            (
                                                                                                [0] => Array
                                                                                                    (
                                                                                                        [span_multi] => Array
                                                                                                            (
                                                                                                                [match] => Array
                                                                                                                    (
                                                                                                                        [regexp] => Array
                                                                                                                            (
                                                                                                                                [custom_44] => .*29xcs.*
                                                                                                                            )

                                                                                                                    )

                                                                                                            )

                                                                                                    )

                                                                                            )

                                                                                        [slop] => 0
                                                                                        [in_order] => 1
                                                                                    )

                                                                            )

                                                                    )

                                                            )

                                                    )

                                            )

                                        [1] => Array
                                            (
                                                [term] => Array
                                                    (
                                                        [deleted] => 0
                                                    )

                                            )

                                        [2] => Array
                                            (
                                                [terms] => Array
                                                    (
                                                        [publication_id] => Array
                                                            (
                                                                [0] => 35627
                                                            )

                                                    )

                                            )

                                        [3] => Array
                                            (
                                                [term] => Array
                                                    (
                                                        [custom_61] => 1
                                                    )

                                            )

                                    )

                            )

                    )

            )

    )

[sort] => Array
    (
        [0] => Array
            (
                [custom_44] => asc
            )

    )

)

这可以在弹性搜索中实现吗?得到结果后需要排序吗?

标签: phpelasticsearchelasticsearch-2.0

解决方案


ElasticSearch 将根据特定字段的评分与您的输入进行比较,对结果进行排序。

例如,如果您搜索“Z1234 S1234 T2344”,它会尝试查找尽可能靠近单个输入和分析器的文档,然后它会根据邻近度分数对结果进行相应的排名。

例如,考虑以下索引:

POST test/doc/
{
  "product_name" : "Z1234"
}

POST test/doc/
{
  "product_name" : "Z1235"
}


POST test/doc
{
  "product_name" : "S1234"
}

POST test/doc
{
  "product_name" : "T2344"
}

如果您搜索 "Z1234 S1234 T2344" ,它将根据分数对结果进行排序(结果更接近您的输入),然后将剩余的排序如下(诸如“Z1235”之类的值)

GET test/doc/_search
{
    "query": {
        "match" : {
            "product_name" : {
                "query" : "Z1234 S1234 T2344",
                "operator" : "OR",
                "fuzziness": 1
            }
        }
    }
}





"hits": {
    "total": 5,
    "max_score": 1.2476649,
    "hits": [
      {
        "_index": "test",
        "_type": "doc",
        "_id": "AWViqiCOOSSVvlNCAXVu",
        "_score": 1.2476649,
        "_source": {
          "product_name": "Z1234"
        }
      },
      {
        "_index": "test",
        "_type": "doc",
        "_id": "AWViqlZ2OSSVvlNCAXV7",
        "_score": 0.6931472,
        "_source": {
          "product_name": "T2344"
        }
      },
      {
        "_index": "test",
        "_type": "doc",
        "_id": "AWViqj9UOSSVvlNCAXV2",
        "_score": 0.51782775,
        "_source": {
          "product_name": "S1234"
        }
      },
      {
        "_index": "test",
        "_type": "doc",
        "_id": "AWVir1UeOSSVvlNCAXpB",
        "_score": 0.23014566,
        "_source": {
          "product_name": "Z1235"
        }
      },
      {
        "_index": "test",
        "_type": "doc",
        "_id": "AWVirhwlOSSVvlNCAXkQ",
        "_score": 0.23014566,
        "_source": {
          "product_name": "Z1235"
        }
      }
    ]
  }
}

现在,如果您不想按分数排序,而是按字段名称排序,则排序的字段应包含 doc 值(默认为 Text 字段)

GET test/doc/_search
{
  "query": {
    "match": {
      "product_name": {
        "query": "Z1234 S1234 T2344",
        "operator": "OR",
        "fuzziness": 1
      }
    }
  },
  "sort": [
    {
      "product_name.keyword": {
        "order": "desc"
      }
    }
  ]
}



{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": null,
    "hits": [
      {
        "_index": "test",
        "_type": "doc",
        "_id": "AWVitbfmOSSVvlNCAYA8",
        "_score": null,
        "_source": {
          "product_name": "Z1235"
        },
        "sort": [
          "Z1235"
        ]
      },
      {
        "_index": "test",
        "_type": "doc",
        "_id": "AWVita_pOSSVvlNCAYA7",
        "_score": null,
        "_source": {
          "product_name": "Z1234"
        },
        "sort": [
          "Z1234"
        ]
      },
      {
        "_index": "test",
        "_type": "doc",
        "_id": "AWVitcPKOSSVvlNCAYBA",
        "_score": null,
        "_source": {
          "product_name": "T2344"
        },
        "sort": [
          "T2344"
        ]
      },
      {
        "_index": "test",
        "_type": "doc",
        "_id": "AWVitb1GOSSVvlNCAYA_",
        "_score": null,
        "_source": {
          "product_name": "S1234"
        },
        "sort": [
          "S1234"
        ]
      }
    ]
  }
}

推荐阅读