创建 Mapping
Mapping 是必须有自己进行创建的,这里还需要进行 ik 的分词,如果使用的默认识别有可能数据类型非常乱,而且还不具备分词功能。
$ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_mapping -d‘ { "fulltext" : { "_all" : { "analyzer" : "ik_max_word" , "search_analyzer" : "ik_max_word" , "term_vector" : "no" , "store" : "false" }, "properties" : { "@timestamp" : { "type" : "date" }, "company_label" : { "type" : "keyword" }, "company_name" : { "type" : "keyword" }, "company_recruitment_url" : { "type" : "keyword" }, "jobs_info" : { "type" : "text" , "fielddata" : "true" , "analyzer" : "ik_max_word" , "search_analyzer" : "ik_max_word" , "include_in_all" : "true" , "boost" : 8 }, "position_address" : { "type" : "keyword" }, "position_name" : { "type" : "keyword" }, "position_requirements_label" : { "type" : "keyword" }, "position_salary" : { "type" : "keyword" }, "position_url" : { "type" : "keyword" }, "release_time" : { "type" : "date" }, "hiring_number" : { "type" : "keyword" }, "work_experience" : { "type" : "keyword" } } } }‘ |
查询概要
分页和结果集大小(form、size)
Elasticsearch能控制想要的最多结果数以及想从哪个结果开始。下面是可以在请求体中添加的两个额外参数。 from:该属性指定我们希望在结果中返回的起始文档。它的默认值是0,表示想要得到从第一个文档开始的结果。 size:该属性指定了一次查询中返回的最大文档数,默认值为10。如果只对切面结果感兴趣,并不关心文档本身,可以把这个参数设置成0。 如果想让查询从第2个文档开始返回20个文档,可以发送如下查询:
$ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_search ?pretty -d ‘ { "version" : true , "query" : { "match" : { "position_address" : "南京 佛山 东莞" } }, "from" : "10" , "size" : "10" }‘ # 从第 10 个文档开始列出结果,只列出 10 个, 并打印 version 版本号这里的 version 为修改过的次数。 |
选择返回字段(fields)
- 如果没有定义fields数组,它将用默认值,如果有就返回_source字段;
- 如果使用_source字段,并且请求一个没有存储的字段,那么这个字段将从_source字段中提取(然而,这需要额外的处理);
- 如果想返回所有的存储字段,只需传入星号()作为字段名字。 *从性能的角度,返回_source字段比返回多个存储字段更好。
此案例已在上述案例中使用。
部分字段(include、exclude)
Elasticsearch公开了部分字段对象的include和exclude属性,所以可以基于这些属性来包含或排除字段。例如,为了在查询中包括以titl开头且排除以chara开头的字段,发出以下查询:
{ "partial_fields" : { "partial1" : { "include" : [ "titl*" ], "exclude" : [ "chara*" ] } }, "query" : { "query_string" : { "query" : "title:crime" } } } |
脚本字段 (script_fields)
在JSON的查询对象中加上script_fields部分,添加上每个想返回的脚本值的名字。若要返回一个叫correctYear的值,它用year字段减去1800计算得来,运行以下查询:
{ "script_fields" : { "correctYear" : { "script" : "doc[‘year‘].value - 1800" } }, "query" : { "query_string" : { "query" : "title:crime" } } } |
上面的示例中使用了doc符号,它让我们捕获了返回结果,从而让脚本执行速度更快,但也导致了更高的内存消耗,并且限制了只能用单个字段的单个值。如果关心内存的使用,或者使用的是更复杂的字段值,可以用_source字段。使用此字段的查询如下所示
{ "script_fields" : { "correctYear" : { "script" : "_source.year - 1800" } }, "query" : { "query_string" : { "query" : "title:crime" } } } |
返回格式如下:
{ "took" : 1, "timed_out" : false , "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 0.15342641, "hits" : [ { "_index" : "library" , "_type" : "book" , "_id" : "4" , "_score" : 0.15342641, "fields" : { "correctYear" : [ 86 ] } } ] } } |
传参数到脚本字段中(script_fields)
一个脚本字段的特性:可传入额外的参数。可以使用一个变量名称,并把值传入params节中,而不是直接把1800写在等式中。这样做以后,查询将如下所示:
{ "script_fields" : { "correctYear" : { "script" : "_source.year - paramYear" , "params" : { "paramYear" : 1800 } } }, "query" : { "query_string" : { "query" : "title:crime" } } } |
基本查询
基本查询就是使用请求进行查询。
match 查询
match 查询有两种方式:match_all 和 match ,match_all 不用添加任何条件进行全局查询,match 则会根据我们所需的条件进行查询,match_all 查询格式如下:
$ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_search ?pretty -d ‘{ "query" : { "match_all" : {} }, "size" : 1 }‘ |
搜索测试在北京的职位,只列出 10 个
$ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_search -d‘ { "query" : { "match" : { "position_address" : "北京" } }, "_source" : [ "position_name" ], "size" : ‘10‘ }‘ # 下面查询 position_address 字段,包含 南京 or 佛山 or 东莞 的信息 $ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_search ?pretty -d ‘ { "query" : { "match" : { "position_address" : "南京 佛山 东莞" } } }‘ # 可以修改类型是否是 or 或者 and 匹配,修改 operator 字段为 or 或者 and 即可 $ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_search ?pretty -d ‘ { "query" : { "match" : { "position_address" : "南京 佛山 东莞" , "operator" : "and" } } }‘ |
复合查询
布尔查询
- should:被它封装的布尔查询可能被匹配,也可能不被匹配。被匹配的should节点数由minimum_should_match参数控制。
- must:被它封装的布尔查询必须被匹配,文档才会返回。
- must_not:被它封装的布尔查询必须不被匹配,文档才会返回。
查询组合包含 北京 与 佛山 岗位地点的信息
$ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_search ?pretty -d‘ { "query" : { "bool" : { "must" : [ { "match" : { "position_address" : "北京" }}, { "match" : { "position_address" : "佛山" }} ] } }, "size" : "100" }‘ # must 查询必须都是为真才返回这里肯定没有数据 $ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_search ?pretty -d‘ { "query" : { "bool" : { "should" : [ { "match" : { "position_address" : "北京" }}, { "match" : { "position_address" : "佛山" }} ] } }, "size" : "100" }‘ # should 查询只要有一个返回为真侧会被查询到,之后以评分值列出查询相似比较高的如果北京已经查询完毕但是我们设置的 size 查询长度还是比较大这时候就会查询到,如:南京等信息。 $ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_search ?pretty -d‘ { "query" : { "bool" : { "must_not" : [ { "match" : { "position_address" : "北京" }}, { "match" : { "position_address" : "佛山" }} ] } }, "size" : "100" }‘ # must_not 查询组合都为假,取反,列出没有被匹配到的信息。 |
可以使用上述组合条件进行复杂查询。
范围查询
- gte:范围查询将匹配字段值大于或等于此参数值的文档。
- gt:范围查询将匹配字段值大于此参数值的文档。
- lte:范围查询将匹配字段值小于或等于此参数值的文档。
- lt:范围查询将匹配字段值小于此参数值的文档。
列出 100 条,条件是薪资 3~7 的岗位,只列出名称及薪资
$ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_search ?pretty -d ‘{ "query" : { "bool" : { "must" : { "match_all" : {} }, "filter" : { "range" : { "position_salary" : { "gte" : 3, "lte" : 7 } } } } }, "_source" : [ "position_name" , "position_salary" ], "size" : "100" }‘ |
同字段多条件查询
判断 position_address 字段是否有 北京 或者 佛山的语句,默认列出 10 条
$ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_search ?pretty -d ‘{ "query" : { "terms" : { "position_address" : [ "北京" , "佛山" ] } } }‘ |
match_phrase 查询(slop)
这个可以查询类似 a x b,其中x是未知的。即知道了a和b,x未知的结果也可以查询出来。
{ "query" : { "match_phrase" : { "title" : { "query" : "crime punishment" , "slop" : 1 } } } } |
注意,我们从查询中移除了and一词,但因为slop参数设置为1,它仍将匹配我们的文档。
slop:这是一个整数值,该值定义了文本查询中的词条和词条之间可以有多少个未知词条,以被视为跟一个短语匹配。此参数的默认值是0,这意味着,不允许有额外的词条,即上面的x可以是多个。
match_phrase_prefix 查询
{ "query" : { "match_phrase_prefix" : { "title" : { "query" : "crime and punishm" , "slop" : 1, "max_expansions" : 20 } } } } |
注意,我们没有提供完整的“crime and punishment”短语,而只是提供“crime and punishm”,该查询仍将匹配我们的文档。
聚合操作
使用 group 进行分组操作,这里需要打开 filedata 配置,否则会报错,搜索内容并以 position_address 字段分组进行查询,默认只列出 10 条
$ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_search ?pretty -d ‘{ "size" : "0" , "aggs" : { "group_by_state" : { "terms" : { "field" : "position_address" } } } }‘ |
Multi_match 查询
multi_match
查询提供了一个简便的方法用来对多个字段执行相同的查询,multi_match 查询和 match 查询一样,但是可以通过 fields 参数针对多个字段查询。当然,match 查询中可以使用的所有参数同样可以在 multi_match 查询中使用。所以,如果想修改 match 查询,让它针对 title 和 otitle 字段运行,那么运行以下查询:
{ "query" : { "multi_match" : { "query" : "crime punishment" , "fields" : [ "title" , "otitle" ] } } } |
样例操作
$ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_search ?pretty -d ‘ { "query" : { "multi_match" : { "query" : "北京" , "type" : "most_fields" , "fields" : [ "jobs_info" , "jobs_info.std" ] } } }‘ |
提升字段重要性,查询的评分是倍数关系
$ curl -XPOST http: //localhost :9200 /scrapy-51job/fulltext/_search ?pretty -d ‘ { "query" : { "multi_match" : { "query" : "北京" , "type" : "most_fields" , "fields" : [ "jobs_info^10" , "jobs_info.std" ] } } }‘ |
前缀查询
想找到所有title字段以cri开始的文档,可以运行以下查询:
{ "query" : { "prefix" : { "title" : "cri" } } } |
通配符查询
这里?表示任意字符:
{ "query" : { "wildcard" : { "title" : "cr?me" } } } |