这是一个系列的第二篇,这篇主要介绍了如何将数据录入到ElasticSearch中。

目录

简介

一般的搜索引擎(例如google,百度)都有一个爬虫,这个爬虫会抓取互联网上链接的内容,把这些内容保存进自己的数据库。换句话说,这个数据库里面保存着每张网页上的文字。本系列教程专注于搜索技术本身,所以不在爬虫技术上做展开。我们采用自己往数据库里面存东西的方式,以模拟爬虫的行为。

录入的数据介绍

我最近在玩一个叫Fate Grand Order的手游。比方说我们现在做一个关于这个手游里面卡牌的搜索引擎。让我们来建立一个关于该手游里面卡牌的数据库吧!

为了简便起见,我们只录入每张牌的名字、职阶和简介。比如下面一张吾王的牌:

saber

我们只在数据库中存入:

1
2
3
4
5
{
name: "阿尔托莉雅・潘德拉贡",
class: "Saber",
description: "不列颠传说中的王,被称为骑士王。阿尔托莉雅是幼名,从成为王的那一天起就被称为亚瑟王。在那个骑士道如花般凋零的时代,用手中的圣剑为不列颠带来了短暂的和平与最后的繁荣。虽然史实上是男性,但在这个世界似乎是男装的丽人。"
}

其中,name字段代表该英灵(卡牌)的名字,class代表该卡牌在游戏里面的职阶,description是这张卡牌的简介。

不过在动手存数据之前,我们要先了解一下ElasticSearch的一些基础知识。

ElasticSearch的一些基础知识

上一篇说到,ES是一个支持全文搜索的开源数据库。ES并没有SQL数据库中的表的概念,也没有mongoDB中的Collection的概念。在ES中,类似的概念由Index和Type组成。 (注: ES还有Cluster和Node的概念,不过这个只在使用数据库集群的时候才会用到,这里面略过)

Index

官方文档中,对Index的解释如下:

An index is a collection of documents that have somewhat similar characteristics.

For example, you can have an index for customer data, another index for a product catalog, and yet another index for order data. An index is identified by a name (that must be all lowercase) and this name is used to refer to the index when performing indexing, search, update, and delete operations against the documents in it.

目前阶段你可以认为index相当于其他数据库系统的database。等到熟悉之后你会了解到两者之间还有些差别。

Type

官方文档中,对Type的解释如下:

Within an index, you can define one or more types. A type is a logical category/partition of your index whose semantics is completely up to you.

In general, a type is defined for documents that have a set of common fields. For example, let’s assume you run a blogging platform and store all your data in a single index. In this index, you may define a type for user data, another type for blog data, and yet another type for comments data.

目前阶段你可以认为type相当于其他数据库系统的表。

Document

最后,ES里面,每条数据成为一个Document:

A document is a basic unit of information that can be indexed.

For example, you can have a document for a single customer, another document for a single product, and yet another for a single order. This document is expressed in JSON (JavaScript Object Notation) which is an ubiquitous internet data interchange format.

Within an index/type, you can store as many documents as you want. Note that although a document physically resides in an index, a document actually must be indexed/assigned to a type inside an index.

我们拿我们的数据作为例子,构建数据库。我们的游戏简称叫做fgo,所以我们index就起名为fgo。卡牌的类别叫做servant(英灵),所以我们type就起名为servant。吾王这张牌是游戏中第二张卡牌,所以id我们设为2。接下去我们在Kibana中输入以下命令,新建一个数据:

1
2
3
4
5
6
POST /fgo/servant/2
{
"name": "阿尔托莉雅・潘德拉贡",
"class": "Saber",
"description": "不列颠传说中的王,被称为骑士王。阿尔托莉雅是幼名,从成为王的那一天起就被称为亚瑟王。在那个骑士道如花般凋零的时代,用手中的圣剑为不列颠带来了短暂的和平与最后的繁荣。虽然史实上是男性,但在这个世界似乎是男装的丽人。"
}

ElasticSearch返回:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"_index": "fgo",
"_type": "servant",
"_id": "2",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": true
}

表示成功。

这里解释一下。 我们请求的方法是POST,路径是/fgo/servant/2,路径的格式是/{index}/{type}/{id}。当然,你也可以不明写id,直接请求POST /fgo/servant/,这样系统会自动帮你的document新建一个id。

请求下面的那段数据,就是请求的body了。就是我们要储存的内容。储存的内容是JSON格式,key一定是string,value可以是整数、浮点数、字符串、数组、json对象、时间等等,具体可以去查文档。

到此为止,我们成功地录入了一条数据。接下来我们再多录入几条数据。

多数据一起录入

ES有许多API,其中一个是批量录入多条数据。跟着我在Kibana中输入以下命令:

1
2
3
4
5
6
7
POST /fgo/servant/_bulk
{"create": {"_id": 5}}
{"name": "尼禄・克劳狄乌斯","class": "Saber","description": "自称是男装的丽人。既自我至上主义又自私任性,明朗豁达,像小孩子一样天真无邪、被万人爱戴的无所不能恣意妄为的皇帝。本名,尼禄・克劳狄乌斯・凯撒・奥古斯都・日耳曼尼库斯。罗马帝国的第5代皇帝。生涯被涂上谋略与毒之色彩的恶名昭彰的暴君。"}
{"create": {"_id": 11}}
{"name": "卫宫","class": "Archer","description": "由于不是和其他英灵一样出自典故,不能被称为正统的英灵。由于这个英灵被称为守护者,所以它就像是由人类“应该存活下去”这个集体无意识中诞生出的像是防卫装置的东西。这个防卫装置所在的那一方被称为人类立场的抑止力,要点在于要选择没有名字的人们,没有知名度的正义的代理人。"}
{"create": {"_id": 12}}
{"name": "吉尔伽美什","class": "Archer","description": "公元以前统治着苏美尔的都市国家乌鲁克的半神半人的王者。不仅仅是传说而是真实存在的人物,记述于人类最古的叙事诗《吉尔伽美什叙事诗》中的王。"}

我们一口气输入了3条数据。我们先来欣赏下这三张卡牌☺️:

尼禄尼禄
卫宫卫宫
吉尔伽美什吉尔伽美什

这下我们的数据库里面已经有了4个英灵(卡牌),接下去我们可以开始搜索了。

一起进入第三篇:全文搜索


题图来源:Designed by Freepik

ElasticSearch官方教程:点此进入
Kibana官方教程:点此进入