Elasticsearch可以利用DSL句法构建各种复杂的查询语法,完成搜索操作,下面看看几个应用场景。
复合查询
需求:title必须包含elasticsearch,content可以包含elasticsearch也可以不包含,author_id必须不为111,对应的DSL语句如下:
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "elasticsearch"
}
}
],
"should": [
{
"match": {
"content": "elasticsearch"
}
}
],
"must_not": [
{
"match": {
"author_id": 111
}
}
]
}
}
}
搜索需求:年龄必须大于等于30,同时join_date必须是2016-01-01,对应DSL语句如下:
{
"query": {
"bool": {
"must": [
{
"match": {
"join_date": "2016-01-01"
}
}
],
"filter": {
"range": {
"age": {
"gte": 30
}
}
}
}
}
}
filter,仅仅只是按照搜索条件过滤出需要的数据而已,不计算任何相关度分数,对相关度没有任何影响,query,会去计算每个document相对于搜索条件的相关度,并按照相关度进行排序。
multi_match用法
{
"query": {
"multi_match": {
"query": "test",
"fields": ["test_field", "test_field1"]
}
}
}
如何定位不合法的搜索及其原因
一般用在那种特别复杂庞大的搜索下,比如你一下子写了上百行的搜索,这个时候可以先用validate api去验证一下,搜索是否合法,具体用法如下:
GET /unrecall_query_minning/doc/_validate/query?explain
{
"query": {
"mach": {"poi_name":"好再来"}
}
}
执行完后,会给出报错和提示:
{
"valid" : false,
"error" : "ParsingException[unknown query [mach] did you mean [match]?]; nested: NamedObjectNotFoundException[[3:13] unknown field [mach]];; org.elasticsearch.xcontent.NamedObjectNotFoundException: [3:13] unknown field [mach]"
}
如何将一个field索引两次来解决字符串排序问题
如果对一个string field进行排序,结果往往不准确,因为分词后是多个单词,再排序就不是我们想要的结果了,通常解决方案是,将一个string field建立两次索引,一个分词,用来进行搜索;一个不分词,用来进行排序。
首先建立mapings,对title字段建立两次索引:
PUT /website
{
"mappings": {
"article": {
"properties": {
"title": {
"type": "text",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
},
"fielddata": true
},
"content": {
"type": "text"
},
"post_date": {
"type": "date"
},
"author_id": {
"type": "long"
}
}
}
}
}
接着查询,(注意:数据请自行插入)
GET /website/article/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"title.raw": {
"order": "desc"
}
}
]
}