August Rush

一个还在努力成长的小火汁!

游龙当归海,海不迎我自来也。

We create our own demons.

You can reach me at augustrush0923@gmail.com
Elasticsearch初体验
发布:2023年01月31日 | 作者:augustrush | 阅读量: 704

Elasticsearch

Elasticsearch是面向文档型数据库,一条数据在这里就是一个文档。

关系型数据库MySQL存储数据的概念与Elasticsearch里存储文档数据的对比:

https://cdn.hdcheung.cn/static/img/20220811195634.png

Elasticsearch里的Index可以看作一个库,而Type相当于表,Documents则相当于表的行。Fields则相当于表的列。

在新版Elasticsearch中,Type的概念已经被逐渐弱化。Elasticsearch 6.X中,一个index下已经只能包含一个type

倒排索引

索引操作

创建索引

对比关系型数据库,创建索引就等同于创建数据库。

只需向ES服务器发PUT请求:

# http://<ES服务地址>/<索引名称>
curl -X PUT http://localhost:9200/supermarket
# 返回值:
{
    "acknowledged": true,
    "shards_acknowledged": true,
    "index": "supermarket"
}

查询指定索引

只需向ES服务器发GET请求:

# http://<ES服务地址>/<索引名称>
curl http://localhost:9200/supermarket
# 返回值:
{
    "supermarket": {
        "aliases": {},
        "mappings": {},
        "settings": {
            "index": {
                "creation_date": "1660186748982",
                "number_of_shards": "1",
                "number_of_replicas": "1",
                "uuid": "jlllGg_3TRmLKtC8r_ZDoA",
                "version": {
                    "created": "7080199"
                },
                "provided_name": "supermarket"
            }
        }
    }
}

查询所有索引

# http://<ES服务器地址>/_cat/indices?v
curl http://localhost:9200/_cat/indices?v

返回值:

health status index       uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   supermarket jlllGg_3TRmLKtC8r_ZDoA   1   1          0            0       208b           208b
yellow open   bookstore   6r4T-ng1Qeufs4jJpJPahw   1   1          1            0      4.4kb          4.4kb
yellow open   shopping    2_vlSiDmRYuOG6eLRudKOg   1   1          0            0       208b           208b

删除索引

只需向ES服务器发DELETE请求:

# http://<ES服务地址>/<索引名称>
curl -X DELETE http://localhost:9200/supermarket

返回值:

{
        "acknowledged":true
}

文档操作

创建文档

这里的文档可以类比为关系型数据库中的表数据,添加的数据格式为JSON格式

只需向ES服务器发送POST请求:

# POST http://<ES服务地址>/<索引名称>/_doc
# On Windows, escape the double quotes
curl -H "Content-Type: application/json" -X POST -d {\"title\":\"AppleWatch6\",\"category\":\"Apple\",\"price\":3999.00} http://localhost:9200/supermarket/_doc
# For *nix or Mac OSX, add a single quote
curl -H "Content-Type: application/json" -X POST -d '{"title":"AppleWatch6","category":"Apple","price":3999.00}' http://localhost:9200/supermarket/_doc

返回结果:

{
    "_index": "supermarket",
    "_type": "_doc",
    "_id": "sUNui4IBGBS9mFAECUdX",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}

这种方式发送请求不是幂等性的,每次都会返回不一样的随机ID,代表生成了多条同样的数据。如果想指定返回ID可以用下面的请求:

# POST http://<ES服务器地址>/<索引名称>/_doc/<id>
curl -H "Content-Type: application/json" -X POST -d {\"title\":\"AppleWatch6\",\"category\":\"Apple\",\"price\":3999.00} http://localhost:9200/supermarket/_doc/1001/

返回结果:

{
    "_index": "supermarket",
    "_type": "_doc",
    "_id": "1001",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 2,
    "_primary_term": 1
}

如果要生成指定ID的数据时,就是幂等性操作,遂也可以使用PUT方法来进行新建文档。

# PUT http://<ES服务器地址>/<索引名称>/_doc/<id>
curl -H "Content-Type: application/json" -X PUT -d {\"title\":\"AppleWatch6\",\"category\":\"Apple\",\"price\":3999.00} http://localhost:9200/supermarket/_doc/1001/

返回结果:

{
    "_index": "supermarket",
    "_type": "_doc",
    "_id": "1003",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 3,
    "_primary_term": 1
}

同时还可以用/_create来新建指定ID的数据

# PUT http://<ES服务器地址>/<索引名称>/_create/<id>
curl -H "Content-Type: application/json" -X PUT -d {\"title\":\"AppleWatch6\",\"category\":\"Apple\",\"price\":3999.00} http://localhost:9200/supermarket/_create/1001/

# POST http://<ES服务器地址>/<索引名称>/_create/<id>
curl -H "Content-Type: application/json" -X POST -d {\"title\":\"AppleWatch6\",\"category\":\"Apple\",\"price\":3999.00} http://localhost:9200/supermarket/_create/1001/
{
    "_index": "supermarket",
    "_type": "_doc",
    "_id": "1005",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 6,
    "_primary_term": 1
}

查询文档

查询指定文档

# GET http://<ES服务器地址>/<索引名称>/_doc/<id>

curl -X GET http://localhost:9200/supermarket/_doc/1001

返回结果:

{
    "_index": "supermarket",
    "_type": "_doc",
    "_id": "1002",
    "_version": 1,
    "_seq_no": 2,
    "_primary_term": 1,
    "found": true,
    "_source": {
        "title": "Apple Watch 6",
        "category": "Apple",
        "price": 3999.00
    }
}

查询所有文档

# GET http://<ES服务器地址>/<索引名称>/_search
curl -X GET http://localhost:9200/supermarket/_search

返回结果:

{
    "took": 1,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 8,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "sUNui4IBGBS9mFAECUdX",
                "_score": 1.0,
                "_source": {
                    "title": "Apple Watch 6",
                    "category": "Apple",
                    "price": 3999.00
                }
            },
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "1002",
                "_score": 1.0,
                "_source": {
                    "title": "Apple Watch 6",
                    "category": "Apple",
                    "price": 3999.00
                }
            }
        ]
    }
}

文档修改

全量数据更新

# PUT http://<ES服务器地址>/<索引名>/_doc/<id>
curl -X PUT -H "Content-Type: application/json" -d {\"title\":\"xiaomi10Ultra\",\"category\":\"xiaomi\",\"price\":3999.00} http://localhost:9200/supermarket/_doc/1002

返回结果:

{
    "_index": "supermarket",
    "_type": "_doc",
    "_id": "1002",
    "_version": 2,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 9,
    "_primary_term": 1
}

局部数据更新

# POST http://<ES服务器地址>/<索引名>/_update/<id>
curl -X POST -H "Content-Type: application/json" -d {\"doc\": {\"title\":\"HUWAWEI\"}} http://localhost:9200/supermarket/_update/1002
{
    "_index": "supermarket",
    "_type": "_doc",
    "_id": "1002",
    "_version": 3,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 10,
    "_primary_term": 1
}

文档删除

# DELETE http://<ES服务器地址>/<索引名>/_doc/<id>
curl -X DELETE http://localhost:9200/supermarket/_doc/1002
{
    "_index": "supermarket",
    "_type": "_doc",
    "_id": "1002",
    "_version": 1,
    "result": "deleted",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 13,
    "_primary_term": 1
}

条件查询

根据请求路径进行条件查询

# GET http://<ES服务器地址>/<索引名>/_search?q=<字段名>:<字段值>
curl http://localhost:9200/supermarket/_search?q=category:小米

返回结果:

{
    "took": 37,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 2.9855614,
        "hits": [
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "skNvi4IBGBS9mFAECkfu",
                "_score": 2.9855614,
                "_source": {
                    "title": "xiaomi 10 Ultra",
                    "category": "小米",
                    "price": 3999.00
                }
            }
        ]
    }
}

但请求参数放在请求路径中时,如果查询条件是中文,在不同的操作环境会产生乱码的情况导致无法查询出有效数据。

放在请求体里便可解决这个问题:

# GET http://<ES服务器地址>/<索引名>/_search
# 请求体:
{
    "query": {
        "match": {
                        "category": "Apple"
        }
    }
}

curl -X GET -H "Content-Type: application/json" -d {\"query\":{\"match\":{\"category\":\"Apple\"}}} http://localhost:9200/supermarket/_search

返回结果:

{
    "took": 16,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 0.15226628,
        "hits": [
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "sUNui4IBGBS9mFAECUdX",
                "_score": 0.15226628,
                "_source": {
                    "title": "Apple Watch 6",
                    "category": "Apple",
                    "price": 3999.00
                }
            }
        ]
    }
}

还可以通过发送请求体的方式查询所有数据:

# GET http://<ES服务器地址>/<索引名>/_search
# 请求体:
{
    "query": {
        "match_all": {}
    }
}

curl -X GET -H "Content-Type: application/json" -d {\"query\":{\"match_all\":{}}} http://localhost:9200/supermarket/_search

返回结果:

{
    "took": 3,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "sUNui4IBGBS9mFAECUdX",
                "_score": 1.0,
                "_source": {
                    "title": "Apple Watch 6",
                    "category": "Apple",
                    "price": 3999.00
                }
            },
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "skNvi4IBGBS9mFAECkfu",
                "_score": 1.0,
                "_source": {
                    "title": "xiaomi 10 Ultra",
                    "category": "小米",
                    "price": 3999.00
                }
            }
        ]
    }
}

分页查询

from:代表从第几条数据开始

size:代表每页显示多少条数据

做翻页的通用格式为:(页码-1)*每页数据

# GET http://<ES服务器地址>/<索引名>/_search
# 请求体:
{
    "query": {
        "match_all": {}
    },
    "from": 0,
    "size": 5
}

curl -X GET -H "Content-Type: application/json" -d {\"query\":{\"match_all\":{}},\"from\":0,\"size\":5} http://localhost:9200/supermarket/_search

返回结果:

{
    "took": 3,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 7,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "sUNui4IBGBS9mFAECUdX",
                "_score": 1.0,
                "_source": {
                    "title": "Apple Watch 6",
                    "category": "Apple",
                    "price": 3999.00
                }
            },
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "1003",
                "_score": 1.0,
                "_source": {
                    "title": "Apple Watch 6",
                    "category": "Apple",
                    "price": 3999.00
                }
            }
        ]
    }
}

查询指定字段

_source: 查询指定字段列表

# GET http://<ES服务器地址>/<索引名>/_search
# 请求体:
{
    "query": {
        "match_all": {}
    },
    "_source": ["title"]
}

curl -X GET -H "Content-Type:application/json" -d {\"query\":{\"match_all\":{}},\"_source\":[\"title\"]} http://localhost:9200/supermarket/_search

返回结果:

{
    "took": 3,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "sUNui4IBGBS9mFAECUdX",
                "_score": 1.0,
                "_source": {
                    "title": "Apple Watch 6"
                }
            },
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "skNvi4IBGBS9mFAECkfu",
                "_score": 1.0,
                "_source": {
                    "title": "xiaomi 10 Ultra"
                }
            }
        ]
    }
}

查询排序

sort:{”字段名”: {”order”: “desc/asc”}}

# GET http://<ES服务器地址>/<索引名>/_search
# 请求体:
{
    "query": {
        "match_all": {}
    },
    "sort": {
        "price": {
            "order": "desc"
        }
    }
}

curl -X GET -H "Content-Type:application/json" -d {\"query\":{\"match_all\":{}},\"sort\":{\"price\":{\"order\":\"desc\"}}} http://localhost:9200/supermarket/_search

返回结果:

{
    "took": 2,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": null,
        "hits": [
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "sUNui4IBGBS9mFAECUdX",
                "_score": null,
                "_source": {
                    "title": "Apple Watch 6",
                    "category": "Apple",
                    "price": 3999.00
                },
                "sort": [
                    3999.0
                ]
            },
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "skNvi4IBGBS9mFAECkfu",
                "_score": null,
                "_source": {
                    "title": "xiaomi 10 Ultra",
                    "category": "小米",
                    "price": 3999.00
                },
                "sort": [
                    3999.0
                ]
            }
        ]
    }
}

多条件查询

must:所有条件必须同时满足才能执行查询,相当于and

# GET http://<ES服务器地址>/<索引名>/_search
# 请求体:
{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "category": "小米"
                    }
                },
                {
                    "match": {
                        "price": 3999
                    }
                }
            ]
        }
    }
}

curl -H "Content-Type:application/json" -d {\"query\":{\"bool\":{\"must\":[{\"match\":{\"category\":\"小米\"}},{\"match\":{\"price\":3999}}]}}} http://localhost:9200/supermarket/_search

返回结果:

{
    "took": 4,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 3.9855614,
        "hits": [
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "skNvi4IBGBS9mFAECkfu",
                "_score": 3.9855614,
                "_source": {
                    "title": "xiaomi 10 Ultra",
                    "category": "小米",
                    "price": 3999.00
                }
            }
        ]
    }
}

should:所有条件只需满足指定一个即可执行查询,相当于or

# GET http://<ES服务器地址>/<索引名>/_search
# 请求体:
{
    "query": {
        "match_all": {}
    },
    "sort": {
        "price": {
            "order": "desc"
        }
    }
}

curl -H "Content-Type:application/json" -d {\"query\":{\"bool\":{\"should\":[{\"match\":{\"category\":\"Apple\"}},{\"match\":{\"category\":\"小米\"}}]}}} http://localhost:9200/supermarket/_search

返回结果:

{
    "took": 2,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 2.9855614,
        "hits": [
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "skNvi4IBGBS9mFAECkfu",
                "_score": 2.9855614,
                "_source": {
                    "title": "xiaomi 10 Ultra",
                    "category": "小米",
                    "price": 3999.00
                }
            },
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "sUNui4IBGBS9mFAECUdX",
                "_score": 0.15226628,
                "_source": {
                    "title": "Apple Watch 6",
                    "category": "Apple",
                    "price": 3999.00
                }
            }
        ]
    }
}

范围查询

lt:小于

lte:小于等于

gt:大于

gte:大于等于

# GET http://<ES服务器地址>/<索引名>/_search
# 请求体:
{
    "query": {
        "bool": {
            "filter": {
                "range": {
                    "price": {
                        "lt": 3999
                    }
                }
            }
        }
    }
}

curl -H "Content-Type:application/json" -d {\"query\":{\"bool\":{\"filter\":{\"range\":{\"price\":{\"lt\":3999}}}}}} http://localhost:9200/supermarket/_search

返回结果:

{
    "took": 2,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 0.0,
        "hits": [
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "sUNui4IBGBS9mFAECUdX",
                "_score": 0.0,
                "_source": {
                    "title": "Apple Watch 6",
                    "category": "Apple",
                    "price": 3999.00
                }
            },
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "skNvi4IBGBS9mFAECkfu",
                "_score": 0.0,
                "_source": {
                    "title": "xiaomi 10 Ultra",
                    "category": "小米",
                    "price": 3999.00
                }
            }
        ]
    }
}

高亮显示

# GET http://<ES服务器地址>/<索引名>/_search
# 请求体
{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "category": "小"
                    }
                }
            ]
        }
    },
    "highlight": {
        "fields": {
            "category": {}
        }
    }
}

curl -H "Content-Type:application/json" -d {\"query\":{\"match\":{\"category\":\"小\"}},\"highlight\":{\"fields\":{\"category\":{}}}} http://localhost:9200/supermarket/_search

返回结果:

{
    "took": 73,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 1.4927807,
        "hits": [
            {
                "_index": "supermarket",
                "_type": "_doc",
                "_id": "skNvi4IBGBS9mFAECkfu",
                "_score": 1.4927807,
                "_source": {
                    "title": "xiaomi 10 Ultra",
                    "category": "小米",
                    "price": 3999.00
                },
                "highlight": {
                    "category": [
                        "<em>小</em>米"
                    ]
                }
            }
        ]
    }
}

全文检索&完全匹配

elasticsearch插入数据时会默认把数据分词后添加到倒排索引内一份。比如说存进一条中文数据“你好”,es会分别把“你”和“好”维护到倒排索引内。这时进行全文检索时,无论是单查“你”还是“好”都会把“你好”匹配出来。

match默认会对匹配的数据进行全文检索,match_phrase会对匹配的数据进行完全匹配检索。



  • 标签云

  • 支付宝扫码支持一下

  • 微信扫码支持一下



基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建

京ICP备20007446号-1 & 豫公网安备 41100202000460号

网站地图 & RSS | Feed