参考:https://www.digitalocean.com/community/tutorials/how-to-install-java-with-apt-get-on-debian-8
sudo apt-get update
sudo apt-get -y install default-jre
sudo apt-get -y install default-jdk
sudo apt-get install software-properties-common
sudo add-apt-repository "deb http://ppa.launchpad.net/webupd8team/java/ubuntu xenial main"
sudo apt-get update
sudo apt-get install oracle-java8-installer
sudo update-alternatives --config java
# 复制路径,添加到 /etc/environment 文件中
sudo vim /etc/environment
# /etc/environment
JAVA_HOME="/usr/lib/jvm/java-8-oracle"
# 重新加载环境变量文件
source /etc/environment
echo $JAVA_HOME
参考:
https://www.elastic.co/guide/en/elasticsearch/reference/current/deb.html
http://www.ruanyifeng.com/blog/2017/08/elasticsearch.html
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.1.2.deb
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.1.2.deb.sha512
shasum -a 512 -c elasticsearch-6.1.2.deb.sha512
sudo dpkg -i elasticsearch-6.1.2.deb
安装路径:/usr/share/elasticsearch
配置文件:/etc/elasticsearch
数据存储:/var/lib/elasticsearch
curl localhost:9200
network.host: 0.0.0.0
# 判断 init 还是 systemd
ps -p 1
# 若是 init
sudo update-rc.d elasticsearch defaults 95 10
sudo -i service elasticsearch start
sudo -i service elasticsearch stop
# 若是 systemd
sudo /bin/systemctl daemon-reload
sudo /bin/systemctl enable elasticsearch.service
sudo systemctl start elasticsearch.service
sudo systemctl stop elasticsearch.service
参考:https://github.com/medcl/elasticsearch-analysis-ik
方法1:从这里下载安装包:https://github.com/medcl/elasticsearch-analysis-ik/releases
在 /elasticsearch安装路径/plugins/
下进行解压。
方法2:使用elasticsearch-plugin安装 ( version > v5.5.1 )
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.0.0/elasticsearch-analysis-ik-6.0.0.zip
安装后重启 Elasticsearch
curl -XPUT http://localhost:9200/index
curl -XPOST http://localhost:9200/index/fulltext/_mapping -d'
{
"properties": {
"content": {
"type": "text",
"analyzer": "ik_max_word", # 重点在这里,设置分词器
"search_analyzer": "ik_max_word" # 重点在这里,设置分词器
}
}
}'
无论你在任何字段上进行的是全文搜索还是精确查询,match 查询是你可用的标准查询。
如果你在一个全文字段上使用 match 查询,在执行查询前,它将用正确的分析器去分析查询字符串:
{ "match": { "tweet": "About Search" }}
如果在一个精确值的字段上使用它, 例如数字、日期、布尔或者一个 not_analyzed 字符串字段,那么它将会精确匹配给定的值:
{ "match": { "age": 26 }}
{ "match": { "date": "2014-09-01" }}
{ "match": { "public": true }}
{ "match": { "tag": "full_text" }}
multi_match 查询可以在多个字段上执行相同的 match 查询:
{
"multi_match": {
"query": "full text search",
"fields": [ "title", "body" ]
}
}
range 查询找出那些落在指定区间内的数字或者时间:
{
"range": {
"age": {
"gte": 20,
"lt": 30
}
}
}
被允许的操作符如下:
gt => 大于
gte => 大于等于
lt => 小于
lte => 小于等于
term 查询被用于精确值 匹配,这些精确值可能是数字、时间、布尔或者那些 not_analyzed 的字符串:
{ "term": { "age": 26 }}
{ "term": { "date": "2014-09-01" }}
{ "term": { "public": true }}
{ "term": { "tag": "full_text" }}
term 查询对于输入的文本不 分析 ,所以它将给定的值进行精确查询。
terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件:
{ "terms": { "tag": [ "search", "full_text", "nosql" ] }}
exists 查询和 missing 查询被用于查找那些指定字段中有值 (exists) 或无值 (missing) 的文档。这与SQL中的 IS_NULL (missing) 和 NOT IS_NULL (exists) 在本质上具有共性:
{
"exists": {
"field": "title"
}
}
这些查询经常用于某个字段有值的情况和某个字段缺值的情况。
使用 bool
将多查询组合在一起,成为用户自己想要的布尔查询。它接收以下参数:
must
: 文档 必须 匹配这些条件才能被包含进来。
must_not
: 文档 必须不 匹配这些条件才能被包含进来。
should
: 如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分。
filter
: 必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。
{
"bool": {
"must": { "match": { "title": "how to make millions" }},
"must_not": { "match": { "tag": "spam" }},
"should": [
{ "match": { "tag": "starred" }},
{ "range": { "date": { "gte": "2014-01-01" }}}
]
}
}
查找 title 字段匹配 how to make millions 并且不被标识为 spam 的文档。
那些被标识为 starred 或在2014之后的文档,将比另外那些文档拥有更高的排名。
如果两者都满足,那么它排名将更高。
如果没有 must 语句,那么至少需要能够匹配其中的一条 should 语句。
但,如果存在至少一条 must 语句,则对 should 语句的匹配没有要求。
如果我们不想因为文档的时间而影响得分,可以用 filter 语句来重写前面的例子:
{
"bool": {
"must": { "match": { "title": "how to make millions" }},
"must_not": { "match": { "tag": "spam" }},
"should": [
{ "match": { "tag": "starred" }}
],
"filter": {
"range": { "date": { "gte": "2014-01-01" }}
}
}
}
通过将 range 查询移到 filter 语句中,我们将它转成不评分的查询,将不再影响文档的相关性排名。由于它现在是一个不评分的查询,可以使用各种对 filter 查询有效的优化手段来提升性能。
所有查询都可以借鉴这种方式。将查询移到 bool 查询的 filter 语句中,这样它就自动的转成一个不评分的 filter 了。
如果你需要通过多个不同的标准来过滤你的文档,bool 查询本身也可以被用做不评分的查询。简单地将它放置到 filter 语句中并在内部构建布尔逻辑:
{
"bool": {
"must": { "match": { "title": "how to make millions" }},
"must_not": { "match": { "tag": "spam" }},
"should": [
{ "match": { "tag": "starred" }}
],
"filter": {
"bool": {
"must": [
{ "range": { "date": { "gte": "2014-01-01" }}},
{ "range": { "price": { "lte": 29.99 }}}
],
"must_not": [
{ "term": { "category": "ebooks" }}
]
}
}
}
}
将 bool 查询包裹在 filter 语句中,我们可以在过滤标准中增加布尔逻辑
constant_score 将一个不变的常量评分应用于所有匹配的文档。
它被经常用于你只需要执行一个 filter 而没有其它查询(例如,评分查询)的情况下。
可以使用它来取代只有 filter 语句的 bool 查询。在性能上是完全相同的,但对于提高查询简洁性和清晰度有很大帮助。
{
"constant_score": {
"filter": {
"term": { "category": "ebooks" }
}
}
}
term 查询被放置在 constant_score 中,转成不评分的 filter。这种方式可以用来取代只有 filter 语句的 bool 查询。
{
"query" : {
"bool" : {
"filter" : { "term" : { "user_id" : 1 }}
}
},
"sort": { "date": { "order": "desc" }}
}
{
"query" : {
"bool" : {
"must": { "match": { "tweet": "manage text search" }},
"filter" : { "term" : { "user_id" : 2 }}
}
},
"sort": [
{ "date": { "order": "desc" }},
{ "_score": { "order": "desc" }}
]
}
SELECT document
FROM products
WHERE price = 20
{
"query" : {
"constant_score" : { # 我们用 constant_score 将 term 查询转化成为过滤器
"filter" : {
"term" : {
"price" : 20
}
}
}
}
}
index
必须为not_analyzed
{
"mappings" : {
"products" : {
"properties" : {
"productID" : {
"type" : "string",
"index" : "not_analyzed" }
}
}
}
}
SELECT product
FROM products
WHERE productID = “XHDK-A-1293-#fJ3”
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"productID" : "XHDK-A-1293-#fJ3" }
}
}
}
}
{
"bool" : {
"must" : [],
"should" : [],
"must_not" : [],
}
}
must
所有的语句都 必须(must) 匹配,与 AND 等价。
must_not
所有的语句都 不能(must not) 匹配,与 NOT 等价。
should
至少有一个语句要匹配,与 OR 等价。
SELECT product
FROM products
WHERE (price = 20 OR productID = “XHDK-A-1293-#fJ3”)
AND (price != 30)
{
"query" : {
"filtered" : { #注意,我们仍然需要一个 filtered 查询将所有的东西包起来。
"filter" : {
"bool" : {
"should" : [
#在 should 语句块里面的两个 term 过滤器与 bool 过滤器是父子关系,两个 term 条件需要匹配其一。
{ "term" : {"price" : 20}},
{ "term" : {"productID" : "XHDK-A-1293-#fJ3"}}
],
"must_not" : {
"term" : {"price" : 30} #如果一个产品的价格是 30 ,那么它会自动被排除,因为它处于 must_not 语句里面
}
}
}
}
}
}
SELECT document
FROM products
WHERE productID = “KDKE-B-9947-#kL5”
OR ( productID = “JODL-X-1937-#pV7”
AND price = 30 )
{
"query" : {
"filtered" : {
"filter" : {
"bool" : {
"should" : [ # 因为 term 和 bool 过滤器是兄弟关系,他们都处于外层的布尔逻辑 should 的内部,返回的命中文档至少须匹配其中一个过滤器的条件。 { "term" : {"productID" : "KDKE-B-9947-#kL5"}}, { "bool" : { "must" : [ # 这两个 term 语句作为兄弟关系,同时处于 must 语句之中,所以返回的命中文档要必须都能同时匹配这两个条件。 { "term" : {"productID" : "JODL-X-1937-#pV7"}}, { "term" : {"price" : 30}} ] }} ] }
}
}
}
}
SELECT document
FROM products
WHERE price in (20,30) # 这条语句仅供参考,并不确切
{
"query" : {
"constant_score" : {
"filter" : {
"terms" : { # 注意这里是 terms,而非 term
"price" : [20, 30]
}
}
}
}
}
{ "tags" : ["search"] }
{ "tags" : ["search", "open_source"] }
尽管第二个文档包含除 search 以外的其他词,它还是被匹配并作为结果返回。
{ "tags" : ["search"], "tag_count" : 1 }
{ "tags" : ["search", "open_source"], "tag_count" : 2 }
一旦增加这个用来索引项 term 数目信息的字段,我们就可以构造一个 constant_score 查询,来确保结果中的文档所包含的词项数量与要求是一致的:
{
"query": {
"constant_score" : {
"filter" : {
"bool" : {
"must" : [ { "term" : { "tags" : "search" } }, # 查找所有包含 term search 的文档。 { "term" : { "tag_count" : 1 } } # 确保文档只有一个标签。 ] }
}
}
}
}
这个查询现在只会匹配具有单个标签 search 的文档,而不是任意一个包含 search 的文档。
range
查询可同时提供包含(inclusive)和不包含(exclusive)这两种范围表达式,可供组合的选项如下:gt
: >
大于(greater than)
lt
: <
小于(less than)
gte
: >=
大于或等于(greater than or equal to)
lte
: <=
小于或等于(less than or equal to)
SELECT document
FROM products
WHERE price BETWEEN 20 AND 40
{
"query" : {
"constant_score" : {
"filter" : {
"range" : {
"price" : { "gte" : 20, "lt" : 40 } }
}
}
}
}
"range" : {
"timestamp" : {
"gt" : "2014-01-01 00:00:00",
"lt" : "2014-01-07 00:00:00"
}
}
当使用它处理日期字段时, range 查询支持对 日期计算(date math) 进行操作,比方说,如果我们想查找时间戳在过去一小时内的所有文档:
"range" : {
"timestamp" : {
"gt" : "now-1h"
}
}
这个过滤器会一直查找时间戳在过去一个小时内的所有文档,让过滤器作为一个时间 滑动窗口(sliding window) 来过滤文档。
日期计算还可以被应用到某个具体的时间,并非只能是一个像 now 这样的占位符。只要在某个日期后加上一个双管符号 (||) 并紧跟一个日期数学表达式就能做到:
"range" : {
"timestamp" : {
"gt" : "2014-01-01 00:00:00",
"lt" : "2014-01-01 00:00:00||+1M" # 早于2014年1月1日加1月(2014年2月1日零时)
}
}
日期计算是 日历相关(calendar aware) 的,所以它不仅知道每月的具体天数,还知道某年的总天数(闰年)等信息。更详细的内容可以参考: 时间格式参考文档 。
SELECT tags
FROM posts
WHERE tags IS NOT NULL
{
"query" : {
"constant_score" : {
"filter" : {
"exists" : { "field" : "tags" }
}
}
}
}
结果:
"hits" : [
{
"_id" : "1",
"_score" : 1.0,
"_source" : { "tags" : ["search"] }
},
{
"_id" : "5",
"_score" : 1.0,
"_source" : { "tags" : ["search", null] } # 尽管文档 5 有 null 值,但它仍会被命中返回。字段之所以存在,是因为标签有实际值( search )可以被索引,所以 null 对过滤不会产生任何影响。
},
{
"_id" : "2",
"_score" : 1.0,
"_source" : { "tags" : ["search", "open source"] }
}
]
SELECT tags
FROM posts
WHERE tags IS NULL
{
"query" : {
"constant_score" : {
"filter": {
"missing" : { "field" : "tags" }
}
}
}
}
结果:
"hits" : [
{
"_id" : "3",
"_score" : 1.0,
"_source" : { "other_field" : "some data" } # tags字段不存在
},
{
"_id" : "4",
"_score" : 1.0,
"_source" : { "tags" : null } # tags 字段为null
}
]
exists
and missing
查询 还可以处理一个对象的内部字段。以下面文档为例:{
"name" : {
"first" : "John",
"last" : "Smith"
}
}
我们不仅可以检查 name.first 和 name.last 的存在性,也可以检查 name ,不过在 映射 中,如上对象的内部是个扁平的字段与值(field-value)的简单键值结构,类似下面这样:
{
"name.first" : "John",
"name.last" : "Smith"
}
那么我们如何用 exists
或 missing
查询 name
字段呢? name
字段并不真实存在于倒排索引中。
原因是当我们执行下面这个过滤的时候:
{
"exists" : { "field" : "name" }
}
实际执行的是:
{
"bool": {
"should": [
{ "exists": { "field": "name.first" }},
{ "exists": { "field": "name.last" }}
]
}
}
这也就意味着,如果 first 和 last 都是空,那么 name 这个命名空间才会被认为不存在。
查找 title 包含 quick 的内容
{
"query": {
"match": {
"title": "QUICK"
}
}
}
Elasticsearch 执行上面这个 match 查询的步骤是:
1.检查字段类型 。
标题 title 字段是一个 string 类型( analyzed )已分析的全文字段,这意味着查询字符串本身也应该被分析。
2.分析查询字符串 。
将查询的字符串 QUICK! 传入标准分析器中,输出的结果是单个项 quick 。因为只有一个单词项,所以 match 查询执行的是单个底层 term 查询。
3.查找匹配文档 。
用 term 查询在倒排索引中查找 quick 然后获取一组包含该项的文档,本例的结果是文档:1、2 和 3 。
4.为每个文档评分 。
用 term 查询计算每个文档相关度评分 _score ,这是种将 词频(term frequency,即词 quick 在相关文档的 title 字段中出现的频率)和反向文档频率(inverse document frequency,即词 quick 在所有文档的 title 字段中出现的频率),以及字段的长度(即字段越短相关度越高)相结合的计算方式。参见 相关性的介绍 。
查找 title 包含 BROWN 或 DOG 的内容
{
"query": {
"match": {
"title": "BROWN DOG!"
}
}
}
{
"query": {
"match": {
"title": { # match 查询的结构需要做稍许调整才能使用 operator 操作符参数。
"query": "BROWN DOG!",
"operator": "and"
}
}
}
}
{
"query": {
"match": {
"title": {
"query": "quick brown dog",
"minimum_should_match": "75%" # minimum_should_match 最小匹配参数, 这让我们可以指定必须匹配的词项数用来表示一个文档是否相关
}
}
}
}
当给定百分比的时候, minimum_should_match 会做合适的事情:在之前三词项的示例中, 75% 会自动被截断成 66.6% ,即三个里面两个词。无论这个值设置成什么,至少包含一个词项的文档才会被认为是匹配的。
参数 minimum_should_match 的设置非常灵活,可以根据用户输入词项的数目应用不同的规则。完整的信息参考文档 https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-minimum-should-match.html#query-dsl-minimum-should-match
查找 title 字段包含词项 quick 但不包含 lazy 的任意文档。
关于两个 should 语句:一个文档不必包含 brown 或 dog 这两个词项,但如果一旦包含,我们就认为它们 更相关
{
"query": {
"bool": {
"must": { "match": { "title": "quick" }},
"must_not": { "match": { "title": "lazy" }},
"should": [
{ "match": { "title": "brown" }},
{ "match": { "title": "dog" }}
]
}
}
}
bool 查询会为每个文档计算相关度评分 _score , 再将所有匹配的 must 和 should 语句的分数 _score 求和,最后除以 must 和 should 语句的总数。
must_not 语句不会影响评分; 它的作用只是将不相关的文档排除。
所有 must 语句必须匹配,所有 must_not 语句都必须不匹配,should 语句不是必须匹配。
但是,当没有 must 语句的时候,至少有一个 should 语句必须匹配。
我们也可以通过 minimum_should_match 参数控制需要匹配的 should 语句的数量, 它既可以是一个绝对的数字,又可以是个百分比:
{
"query": {
"bool": {
"should": [
{ "match": { "title": "brown" }},
{ "match": { "title": "fox" }},
{ "match": { "title": "dog" }}
],
"minimum_should_match": 2 # 这也可以用百分比表示。
}
}
}
这个查询结果会将所有满足以下条件的文档返回: title 字段包含 “brown” AND “fox” 、 “brown” AND “dog” 或 “fox” AND “dog” 。如果有文档包含所有三个条件,它会比只包含两个的文档更相关。
多词 match 查询只是简单地将生成的 term 查询包裹 在一个 bool 查询中。如果使用默认的 or 操作符,每个 term 查询都被当作 should 语句,这样就要求必须至少匹配一条语句。以下两个查询是等价的:
{
"query": {
"match": { "title": "brown fox"}
}
}
{
"query": {
"bool": {
"should": [
{ "term": { "title": "brown" }},
{ "term": { "title": "fox" }}
]
}
}
}
如果使用 and 操作符,所有的 term 查询都被当作 must 语句,所以 所有(all) 语句都必须匹配。以下两个查询是等价的:
{
"query": {
"match": {
"title": {
"query": "brown fox",
"operator": "and"
}
}
}
}
{
"query": {
"bool": {
"must": [
{ "term": { "title": "brown" }},
{ "term": { "title": "fox" }}
]
}
}
}
如果指定参数 minimum_should_match ,它可以通过 bool 查询直接传递,使以下两个查询等价:
{
"query": {
"match": {
"title": {
"query": "quick brown fox",
"minimum_should_match": "75%"
}
}
}
}
{
"query": {
"bool": {
"should": [
{ "term": { "title": "brown" }},
{ "term": { "title": "fox" }},
{ "term": { "title": "quick" }}
],
"minimum_should_match": 2 #因为只有三条语句,match 查询的参数 minimum_should_match 值 75% 会被截断成 2 。即三条 should 语句中至少有两条必须匹配。
}
}
}
{
"query": {
"bool": {
"must": {
"match": {
"content": { # content 字段必须包含 full 、 text 和 search 所有三个词。
"query": "full text search",
"operator": "and"
}
}
},
"should": [ # 如果 content 字段也包含 Elasticsearch 或 Lucene ,文档会获得更高的评分 _score
{ "match": { "content": "Elasticsearch" }},
{ "match": { "content": "Lucene" }}
]
}
}
}
{
"query": {
"bool": {
"must": {
"match": { # 这些语句使用默认的 boost 值 1 。
"content": {
"query": "full text search",
"operator": "and"
}
}
},
"should": [
{
"match": {
"content": {
"query": "Elasticsearch",
"boost": 3 # 这条语句更为重要,因为它有最高的 boost 值。
}
}
},
{
"match": {
"content": {
"query": "Lucene",
"boost": 2 # 这条语句比使用默认值的更重要,但它的重要性不及 Elasticsearch 语句。
}
}
}
]
}
}
}
{
"query": {
"bool": {
"should": [
{ "match": { "title": "War and Peace" }},
{ "match": { "author": "Leo Tolstoy" }},
{
"bool": {
"should": [# 这里 translator 的权重要小于 title 和 author 的权重 { "match": { "translator": "Constance Garnett" }}, { "match": { "translator": "Louise Maude" }} ] }
}
]
}
}
}
{
"query": {
"bool": {
"should": [
{
"match": { # title 和 author 语句的 boost 值为 2 。
"title": {
"query": "War and Peace",
"boost": 2
}
}
},
{
"match": {
"author": {
"query": "Leo Tolstoy",
"boost": 2
}
}
},
{
"bool": { # 嵌套 bool 语句默认的 boost 值为 1 。
"should": [
{ "match": { "translator": "Constance Garnett" }},
{ "match": { "translator": "Louise Maude" }}
]
}
}
]
}
}
}
dis_max 即分离 最大化查询(Disjunction Max Query)
将任何与任一查询匹配的文档作为结果返回,但只将最佳匹配的评分作为查询的评分结果返回 :
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "Quick pets" }},
{ "match": { "body": "Quick pets" }}
]
}
}
}
{
"hits": [
{
"_id": "1",
"_score": 0.12713557, # 注意两个评分是完全相同的。
"_source": {
"title": "Quick brown rabbits",
"body": "Brown rabbits are commonly seen."
}
},
{
"_id": "2",
"_score": 0.12713557, # 注意两个评分是完全相同的。
"_source": {
"title": "Keeping pets healthy",
"body": "My quick brown fox eats rabbits on a regular basis."
}
}
]
}
我们可能期望同时匹配 title 和 body 字段的文档比只与一个字段匹配的文档的相关度更高,但事实并非如此,因为 dis_max 查询只会简单地使用 单个 最佳匹配语句的评分 _score 作为整体评分。
可以通过指定 tie_breaker 这个参数将其他匹配语句的评分也考虑其中:
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "Quick pets" }},
{ "match": { "body": "Quick pets" }}
],
"tie_breaker": 0.3
}
}
}
结果如下:
{
"hits": [
{
"_id": "2",
"_score": 0.14757764,
"_source": {
"title": "Keeping pets healthy",
"body": "My quick brown fox eats rabbits on a regular basis."
}
},
{
"_id": "1",
"_score": 0.124275915,
"_source": {
"title": "Quick brown rabbits",
"body": "Brown rabbits are commonly seen."
}
}
]
}
tie_breaker 参数提供了一种 dis_max 和 bool 之间的折中选择,它的评分方式如下:
1.获得最佳匹配语句的评分 _score 。
2.将其他匹配语句的评分结果与 tie_breaker 相乘。
3.对以上评分求和并规范化。
4.有了 tie_breaker ,会考虑所有匹配语句,但最佳匹配语句依然占最终结果里的很大一部分。
tie_breaker 可以是 0 到 1 之间的浮点数,其中 0 代表使用 dis_max 最佳匹配语句的普通逻辑, 1 表示所有匹配语句同等重要。最佳的精确值需要根据数据与查询调试得出,但是合理值应该与零接近(处于 0.1 - 0.4 之间),这样就不会颠覆 dis_max 最佳匹配性质的根本。
multi_match 查询为能在多个字段上反复执行相同查询提供了一种便捷方式。
multi_match 多匹配查询的类型有多种,其中的三种恰巧与 了解我们的数据 中介绍的三个场景对应,即: best_fields 、 most_fields 和 cross_fields (最佳字段、多数字段、跨字段)。
默认情况下,查询的类型是 best_fields , 这表示它会为每个字段生成一个 match 查询,然后将它们组合到 dis_max 查询的内部,如下:
{
"dis_max": {
"queries": [
{
"match": {
"title": {
"query": "Quick brown fox",
"minimum_should_match": "30%" }
}
},
{
"match": {
"body": {
"query": "Quick brown fox",
"minimum_should_match": "30%" }
}
},
],
"tie_breaker": 0.3
}
}
上面这个查询用 multi_match 重写成更简洁的形式:
{
"multi_match": {
"query": "Quick brown fox",
"type": "best_fields", # best_fields 类型是默认值,可以不指定。
"fields": [ "title", "body" ],
"tie_breaker": 0.3,
"minimum_should_match": "30%" # 如 minimum_should_match 或 operator 这样的参数会被传递到生成的 match 查询中。
}
}
字段名称可以用模糊匹配的方式给出:任何与模糊模式正则匹配的字段都会被包括在搜索条件中, 例如可以使用以下方式同时匹配 book_title 、 chapter_title 和 section_title (书名、章名、节名)这三个字段:
{
"multi_match": {
"query": "Quick brown fox",
"fields": "*_title"
}
}
可以使用 ^ 字符语法为单个字段提升权重,在字段名称的末尾添加 ^boost , 其中 boost 是一个浮点数:
{
"multi_match": {
"query": "Quick brown fox",
"fields": [ "*_title", "chapter_title^2" ] # chapter_title 这个字段的 boost 值为 2 ,而其他两个字段 book_title 和 section_title 字段的默认 boost 值为 1
}
}
https://github.com/medcl/elasticsearch-analysis-ik
https://www.elastic.co/guide/en/logstash/current/plugins-inputs-jdbc.html
https://github.com/siddontang/go-mysql-elasticsearch
https://www.cnblogs.com/xing901022/p/4947436.html
POST /my_store/products/_bulk
{ "index": { "_id": 1 }}
{ "price" : 10, "productID" : "XHDK-A-1293-#fJ3" }
{ "index": { "_id": 2 }}
{ "price" : 20, "productID" : "KDKE-B-9947-#kL5" }
{ "index": { "_id": 3 }}
{ "price" : 30, "productID" : "JODL-X-1937-#pV7" }
{ "index": { "_id": 4 }}
{ "price" : 30, "productID" : "QQPX-R-3956-#aD8" }
# response
{
"took": 248,
"errors": false,
"items": [
{
"index": {
"_index": "my_store",
"_type": "products",
"_id": "1",
"_version": 1,
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"status": 201
}
},
{
"index": {
"_index": "my_store",
"_type": "products",
"_id": "2",
"_version": 1,
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"status": 201
}
},
{
"index": {
"_index": "my_store",
"_type": "products",
"_id": "3",
"_version": 1,
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"status": 201
}
}
]
}