ElasticSearch中有没有办法让最短(最接近)的单词排在顶部?

时间:2018-10-11 16:31:56

标签: elasticsearch

我的索引中包含以下单词:“ Kem,Kemi,Kemah,Kemer,Kemerburgaz,Kemang,Kembs,Kemnay,Kempley,Kempsey,Kemerovo”。

当我搜索“ Kem”时,我希望“ Kemi”排在最前面,因为它是最接近的词。 (Kem + i = Kemi)。但这并没有我想要的方式。

索引:

const options = [
  {
    id: 'red',
    label: 'Red',
    value: 'red'
  },
  {
    id: 'green',
    label: 'Green',
    value: 'green'
  }
];

class DOContainer extends Component {
  constructor(props) {
    super(props)

    const initialValue = 'red'

    this.state = {
      // Default value. It will be always the same.
      default: initialValue,
      // What's the Radio value. It will be keep in sync with the selected Radio value.
      // Initially it has the same value as `initivalValue`,
      // but later will be updated by `onRadioChange`.
      selected: initialValue,
    }

    this.onRadioChange = this.onRadioChange.bind(this)
  }

  onRadioChange (selected) {
    this.setState({ selected })
  }

  render() {
    const { selected, default } = this.state

    return (
      <Fragment>
        <div className="do-container">
          <h2>choose a color</h2>
          <div>
            <p>color choose</p>
            <Radio
              options={options} name="do" inline
              selected={selected}
              onChange={this.onRadioChange}
            />

            { selected !== default ? <Button /> : null }
          </div>
        </div>
      </Fragment>
    );
  }
}

查询:

{
"settings": {
    "number_of_shards": 1,
    "analysis": {
    "filter": {
        "autocomplete_filter": {
        "type": "edge_ngram",
        "min_gram": 2,
        "max_gram": 15
        }
    },
    "analyzer": {
        "autocomplete": { 
        "type": "custom",
        "tokenizer": "standard",
        "filter": [
            "lowercase",
            "autocomplete_filter"
        ]
        }
    }
    }
},
"mappings": {
    "_doc": {
    "properties": {
        "name": {
            "fields": {
                "keyword": {
                    "type": "keyword"
                }
            },
        "type": "text",
        "similarity": "classic",
        "analyzer": "autocomplete", 
        "search_analyzer": "standard" 
        },
        "id": {
            "type": "keyword"
        },
        "slug": {
            "type": "keyword"
        },
        "type": {
            "type": "keyword"
        }
    }
    }
}
}

结果:

{
"from" : 0, "size" : 10,
"query": {
    "bool": {
    "must": [
        {
        "match": {
            "name": "Kem"
        }
        }
    ],
    "should": [
        {
        "term": {
            "name.keyword": {
            "value": "Kem"            
            }
        }
        }
    ]
    }
}
}
'

现在它们的得分相同,因为我猜每个人都有“ Kem”。但是,如果我做“ match”或“ match_phrase”,结果是一样的。

1 个答案:

答案 0 :(得分:1)

在您的示例中,您似乎希望结果按长度排序。您可以使用脚本来做到这一点。

POST your_index/_doc/_search
{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "Kem"
          }
        }
      ],
      "should": [
        {
          "term": {
            "name.keyword": {
              "value": "Kem"
            }
          }
        }
      ]
    }
  },
  "sort": [
    {
      "_score": {"order": "desc"}
    },
    {
      "_script": {
        "script": "doc['name.keyword'].value.length()",
        "type": "number",
        "order": "asc"
      }
    },
    {
      "name.keyword": {"order": "asc"}
    }
  ]
}