Elasticsearch按字母顺序排序,然后按数字排序

时间:2016-06-03 17:22:23

标签: sorting elasticsearch

我正在寻找一种优雅的方式,首先按字母顺序排序,然后按数字排序。

我目前的解决方案是插入"〜"在使用下一个排序脚本的数字之前,"〜"在" z"之后按字典顺序排列:

"sort": {
  "_script":{
      "script" : "s = doc['name.raw'].value; n = org.elasticsearch.common.primitives.Ints.tryParse(s.split(' ')[0][0]); if (n != null) { '~' + s } else { s }",
      "type" : "string"
  }
 }

但我想知道是否有一个更优雅,也许更高效的解决方案。

输入:

ZBA ABC ...
ABC SDK ...
123 RIU ...
12B BTE ...
11J TRE ...
BCA 642 ...

期望的输出:

ABC SDK ...
BCA 642 ...
ZBA ABC ...
11J TRE ...
12B BTE ...
123 RIU ...

1 个答案:

答案 0 :(得分:2)

您可以使用利用pattern_replace character filter的自定义分析器在索引时执行相同的操作。在索引处执行它比在搜索时为每个查询运行脚本排序更有效。

它与您的解决方案的工作方式相同,即如果我们检测到一个数字,我们会使用波形符PUT /tests { "settings": { "analysis": { "char_filter": { "pre_num": { "type": "pattern_replace", "pattern": "(\\d)", "replacement": "~$1" } }, "analyzer": { "number_tagger": { "type": "custom", "tokenizer": "keyword", "filter": [], "char_filter": [ "pre_num" ] } } } }, "mappings": { "test": { "properties": { "name": { "type": "string", "fields": { "sort": { "type": "string", "analyzer": "number_tagger", "search_analyzer": "standard" } } } } } } } 预先添加该值,否则我们不会执行任何操作,但我们会在索引时和索引处执行此操作POST /tests/test/_bulk {"index": {}} {"name": "ZBA ABC"} {"index": {}} {"name": "ABC SDK"} {"index": {}} {"name": "123 RIU"} {"index": {}} {"name": "12B BTE"} {"index": {}} {"name": "11J TRE"} {"index": {}} {"name": "BCA 642"} 字段中的结果值。

POST /tests/_search
{
  "sort": {
    "name.sort": "asc"
  }
}

然后您可以索引数据

{
  "hits": {
    "hits": [
      {
        "_source": {
          "name": "ABC SDK"
        }
      },
      {
        "_source": {
          "name": "BCA 642"
        }
      },
      {
        "_source": {
          "name": "ZBA ABC"
        }
      },
      {
        "_source": {
          "name": "11J TRE"
        }
      },
      {
        "_source": {
          "name": "12B BTE"
        }
      },
      {
        "_source": {
          "name": "123 RIU"
        }
      }
    ]
  }
}

然后您的查询可能看起来像这样:

#!/bin/bash
# WF 2016-06-04
# get google material design icons
# see http://stackoverflow.com/questions/28684759/import-material-design-icons-into-an-android-project
tmp=/tmp/icons
index=$tmp/index.html
mkdir -p $tmp
cd $tmp
if [ ! -d material-design-icons ]
then
  git clone https://github.com/google/material-design-icons
fi
cat << EOF > $index
<html>
  <head>
    <head>
    <body>
      <h1>Google Material Design Icons</h1>
EOF
for icon in `find . -name *.svg | grep production | grep 48`
do
    svg=`basename $icon .svg`
    category=`echo $icon | cut -f3 -d '/'`
    echo $category $svg.svg
    mkdir -p $tmp/$category
    cp $icon $tmp/$category
    echo "    <img src='"$icon"' title='"$category $svg"' >" >> $index
done
cat << EOF >> $index
  </body>
</html>
EOF

你得到的回应是:

RewriteEngine on

RewriteCond %{THE_REQUEST} /page-(?:%5B|\[)(.*?)(?:%5D|\]) [NC]
RewriteRule ^ /%1 [R,L]