由于经验丰富地使用Elasticsearch的一年,我将介绍一些教程

这篇文章是关于2020年12月21日的Cloudworks圣诞日历。

首先

你好,我是今年初加入云港株式会社的mayoxtuna(@mayoxtuna)。
我最近迷上了一款叫做Apex Legends的战地FPS游戏。

ad_01.png

《Apex Legends》是一款在《泰坦降临》数百年后的世界中,使用各种被称为“传奇”的角色进行3对3对战的游戏。
最近,它也支持跨平台游戏,因此可以与PS4和XBox的玩家一起游戏。
一起来玩吧~!

不是…而是(快点进入正题)…

…)

当回顾2020年时,我觉得我在Elasticsearch上做得不错,所以想要分享一些积累的经验,给大家做一个Elasticsearch的教程。

对于那些想尝试Elasticsearch或者对它感兴趣的人,或许你只是听过它的名字,想知道它能做些什么?请务必来看看。

Elasticsearch的简介

undefined

◯ Elasticsearch是什么?

从公式中引用:

Elasticsearch 在高速可扩展且可索引多样内容,适用于广泛的用例。

– 应用程序搜索
– 网站搜索
– 企业搜索
– 日志记录和分析
– 基础设施指标和容器监控
– 应用程序性能监控(APM)
– 地理空间数据分析和可视化
– 安全分析
– 业务分析

据说。

如果用平易的语言来说,它就是一款快速高效的搜索引擎。

◯ RDB和什么不同?

首先,对于其本身的称呼就存在差异。

RDBElasticsearchデータベースインデックステーブルタイプカラムフィールドレコードドキュメント

使用RESTful API而不是SQL的方式来添加和删除数据,数据以JSON格式进行处理。

最初我对于「呼称不同、不再使用SQL语句而是JSON格式输入」这样的差异有些疑问,虽然基本上RDB和它的构建方式相同,只是速度更快。但是,RDB具有丰富的通用性功能,Elasticsearch也在模仿其功能性改进,让我觉得它有点像RDB。然而,Elasticsearch专注于全文搜索,像Analysis这样的功能在RDB中则没有。此外,在RDB中很少使用多个数据库,但在Elasticsearch中却很常见。此外,如果在RDB中删除数据库在本地环境下是很少发生的,但是在Elasticsearch中可以删除不需要的索引。我认为RDB和Elasticsearch的使用方式虽然相似,但是本质上还是有所差别的。

关于数据的管理方法

在RDB中,我认为一个数据库可以拥有多个表,而在Elasticsearch中,可以根据时间或用户等来创建不同的数据库(索引)。
换句话说,没有太多类似表的概念。虽然可以通过类型(Type)来实现,但从Elasticsearch 7开始,越来越趋向于无类型化,因此我认为这是RDB和Elasticsearch之间的一个重大区别。

在RDB中,一个数据库中包含工作和用户信息,而在Elasticsearch中,通常会将工作和用户信息分开。

在Elasticsearch中,并非将所有的表放在一个数据库中,而是将需要最少的可搜索对象定义为一个数据库的形式。

如果您希望进行复合条件搜索,您可以创建一个复合索引。

此外,在关系型数据库中不会执行数据库删除等操作,但在Elasticsearch中可以删除不需要的索引。根据数据的存储方式,可能需要定期重新构建索引的情况也存在。

◯ 附加内容:对于文本分析的分析等

在RBD中,数据保持不变,但在Elasticsearch中,文本数据会被拆分,转换并保持在所需的形式中。

进行文本分析并将其转化为最佳形式,可以轻松地提取相关的句子。

这里与RDB不同,是非常重要且美味的地方。

分析器由字符过滤器、标记器和令牌过滤器这三个要素组成。

可以使用Kuromoji、icu_normalize等类似的工具。

请允许我忽略这一点。

文本分析 | Elasticsearch 参考文档 [7.10] | 弹性搜索

我建议您查看官方文档了解详细的Elasticsearch规范。

文档也非常详细,发行说明中写明了更改的原因等等,很容易阅读。

准备和确认Elasticsearch的操作

为了避免麻烦的卸载过程,我将使用docker进行安装。

以下是Elasticsearch安装的详细说明,提取了关键部分。

    https://www.elastic.co/guide/en/elasticsearch/reference/7.9/docker.html#docker

这个也在Docker Hub上公开发布了。

    https://hub.docker.com/r/elastic/elasticsearch/

有关Elasticsearch的Docker镜像,有开源版本和非开源版本可供选择。

    https://www.docker.elastic.co/r/elasticsearch/elasticsearch-oss

OSS版本中,默认不包含x-pack。

在本地进行验证时,由于不需要x-pack,我们将使用OSS版。

环境建设

按照公式的方式拉取最新版本的Elasticsearch。

ad_03.png

2. 将进行启动确认

image.png

3. 尝试点击进入

ad_05.png

我們已經確認了啟動。

在终端上使用Ctrl+C来终止进程。

把它转换成Dockerfile格式。

为了安装插件等功能,需要准备一个Dockerfile。
作为安装项目,有可以进行日语分析的kuromoji等工具。

FROM docker.elastic.co/elasticsearch/elasticsearch-oss:7.9.3

RUN elasticsearch-plugin install analysis-kuromoji && \
    elasticsearch-plugin install analysis-icu

USER elasticsearch

5. 准备Kibana

由于在处理Elasticsearch时,在终端上使用JSON格式进行交互非常麻烦,因此我们还将准备Kibana。

Kibana提供了在Elasticsearch中索引的数据搜索和可视化功能。

ad_06.png

创建docker-compose.yml文件。

由于需要将Kibana与Elasticsearch连接并指定Dockerfile,所以需要准备docker-compose.yml。


version: "3"
services:
  elasticsearch-v7.9.3:
    container_name: "elasticsearch"
    build:
      context: .
      dockerfile: ./Dockerfile
    environment:
      - discovery.type=single-node
      - bootstrap.memory_lock=true
      - logger.deprecation.level=debug
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    ports:
      - "9200:9200"
    volumes:
      - elasticsearch-v7.9.3-data:/usr/share/elasticsearch/data

  kibana-v7.9.3:
    image: docker.elastic.co/kibana/kibana-oss:7.9.3
    ports:
      - "5601:5601"
    restart: always
    environment:
      - "ELASTICSEARCH_HOSTS=http://elasticsearch:9200"

volumes:
  elasticsearch-v7.9.3-data:
    driver: local

8. 启动并确认

ad_07.png

成功即将浏览到以下页面,请访问 http://localhost:5601。

ad_08.png

环境已经搭建完毕,辛苦了。

使用方法简单说明

首先,让我们打开开发工具。

    点击屏幕右上方的三个图标
ad_09.png
    点击开发工具
ad_10.png

您可以通过此界面向Elasticsearch投入、检索和删除数据(使用POST/GET/DELETE方法)。

让我们试试参考一下。请将以下文本粘贴过来。

GET _cat/aliases

通过按下以下部分即可执行。
或者可以通过 ⌘+ENTER 来执行。

ad_11.png

当执行完成后,结果将在右侧输出。

让我们亲自体验一下Elasticsearch。

创建一个空的索引

要创建索引,应使用PUT而不是POST。

让我们复制粘贴以下的文本并运行它。

PUT job_offers

只要返回如下这样的内容就表示成功。

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "job_offers"
}

检查指数

基本上,所有的参考系操作都可以使用GET方法完成。

让我们实际确认已创建的索引。

让我们复制粘贴以下的文本并执行一下。


GET _cat/indices

将返回以以下形式的对象。

yellow open job_offers Y99rqJqOSQ6RHnnmOG8jow 1 1  0  0   208b   208b
green  open .kibana_1  3WOY-fXOSiGGCyX8qwEo-A 1 0 13 19 46.2kb 46.2kb

既然确认了它看起来是人造的,我们就来看一下这个索引的详细信息吧。

让我们复制并执行以下语句。

GET job_offers

会返回以下类似的格式。

{
  "job_offers" : {
    "aliases" : { },
    "mappings" : { },
    "settings" : {
      "index" : {
        "creation_date" : "1607079649046",
        "number_of_shards" : "1",
        "number_of_replicas" : "1",
        "uuid" : "Y99rqJqOSQ6RHnnmOG8jow",
        "version" : {
          "created" : "7090399"
        },
        "provided_name" : "job_offers"
      }
    }
  }
}

因为还没有创建数据库,所以还没有任何数据。

删除已创建的索引

对不起,我刚刚做好了,但让我们尝试删除它。

如果在关系数据库(如RDB)中随意删除数据可能会让人感到恐惧,但在Elasticsearch中,索引的删除等操作通常都比较随意。

因为正如前文所述,由于关系型数据库等方面的持有方式思维完全不同。

让我们复制并执行以下文本。

DELETE job_offers

将返回以下格式的内容。

{
  "acknowledged" : true
}

让我们以同样的方式查看索引列表吧。

让我们尝试复制并执行下面的文本。

GET _cat/indices

将返回以下类似的格式。

green open .kibana_1 3WOY-fXOSiGGCyX8qwEo-A 1 0 21 0 23.3kb 23.3kb

和之前不同,现在只剩下一个了。

由於製作與刪除的步驟已經完成,接下來我們將說明實際插入並查看數據的流程。

创建数据

索引可以具有一个或多个类型。
每个文档都被分配了一个唯一的标识符(ID)。

顺便提一下,在Elasticsearch中,我们不需要预先定义类似于表定义的mapping,只需直接输入数据,它会自动解释并保存为数据。

太棒了!

然而,如果在进行POST时指定了不正确的类型并且插入了数据,它将被接受,因此需要注意这一点。

另外,由于会被强制指定类型,可能会与自己所想的不同。

现在应该停止使用这种方法,因为它已被明确指定为不推荐使用的。

因此,我希望本次我们可以通过进行事先定义并插入的方式来推进。

那么,我们立刻开始,这次我们将制作如下所示的内容。

让我们创建一个名为”qiita”的索引,并将标题(title)、描述(description)和用户名(screen_name)放进去。
然后,让我们将ID设置为2434。
(由于用文字表示结构关系会有点复杂,我们将使用JSON来表示。)

{
  qiita: {
    _doc: {
      title: "アドベントカレンダーxx日目のタイトル",
      description: "どうも初めまして。xxと申します。",
      screen_name: "k-waragai"
    }
  }
}

让我们尝试复制粘贴以下文本并执行,以表达这样的内容。

首先,创建索引。

让我们尝试复制并执行以下文本。

PUT qiita

2. mapping的定义

2. 映射的定义

让我们复制并运行以下句子。

PUT qiita/_mapping/
{
  "properties" : {
    "title" : {
      "type" : "text"
    },
    "description" : {
      "type" : "text"
    },
    "screen_name" : {
      "type" : "text"
    }
  }
}

这里有一个补充说明。
在Elasticsearch 6版本之前,可以通过指定类似qiita/article/2434的方式来指定类型名称,但是从Elasticsearch 7版本开始,类型被弃用,并且需要添加include_type_name=true选项来进行指定。顺便说一下,这也是不推荐的,将来会被移除。
因此,如果不指定的话,将会自动附加”_doc”。
因此,将会变成qiita/_doc/2434这样的形式。

以下是对于mapping的一些变更的例子。

    before
{
  "mappings": {
    "article": {
      "properties" : {
        "title" : {
          "type" : "text"
        },
        "description" : {
          "type" : "text"
        },
        "screen_name" : {
          "type" : "text"
        }
      }
    }
  }
}
    after
{
  "mappings": {
    "_doc": {
      "properties" : {
        "title" : {
          "type" : "text"
        },
        "description" : {
          "type" : "text"
        },
        "screen_name" : {
          "type" : "text"
        }
      }
    }
  }
}

虽然多字段也是可能的,但由于这会增加复杂性,所以减少索引的作用,我认为这是一个很好的更新。

现在我们完成了补充。由于已经定义了映射,让我们来确认一下映射是否正确。

3. 确认映射

让我们试着复制粘贴以下的文本并执行。

GET qiita/_mapping

将以以下的形式返回。

{
  "qiita" : {
    "mappings" : {
      "properties" : {
        "title" : {
          "type" : "text"
        },
        "description" : {
          "type" : "text"
        },
        "screen_name" : {
          "type" : "text"
        }
      }
    }
  }
}

你很好地描述了指定为type的文本内容。

请查阅此处有关于type的内容。

    Field data types | Elasticsearch Reference [7.10] | Elastic

4. 插入数据

让我们复制并执行下面的句子。

請注意是使用PUT方法而不是POST方法。

PUT qiita/_doc/2434
{
  "title": "アドベントカレンダーxx日目のタイトル",
  "description": "どうも初めまして。xxと申します。",
  "screen_name": "k-waragai"
} 

以下将返回这样的格式。

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

看起来很顺利地插入了。

让Elasticsearch负责插入_id,来试一试。

让我们复制并执行以下文本。

需要注意的是,与之前情况不同,这里使用的是POST而不是PUT方法。

POST qiita/_doc/
{
  "title": "Elasticsearchチュートリアル書いてみた",
  "description": "チュートリアルです。みんな見てね。",
  "screen_name": "mayoxmayo"
} 

将返回以下格式的内容。

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

与先前不同,_id字段被赋予了一个随机的英数字值。
由于这个_id是唯一的值,所以无论哪个值都可以,只要不重复即可。

让我们来看一下插入的数据的详细信息。

5. 单独查看数据。

让我们复制并执行以下文本。

GET qiita/_doc/2434

以下提供的形式如下。

{
  "_index" : "qiita",
  "_type" : "_doc",
  "_id" : "2434",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "title" : "アドベントカレンダーxx日目のタイトル",
    "description" : "どうも初めまして。xxと申します。",
    "screen_name" : "k-waragai"
  }
}

我们还可以再确认一件事情。

让我们复制并执行以下文本。

※ 此处指定的随机字符串指的是在POST时生成并返回的_id。

GET qiita/_doc/J32eLXYB4YEI6IRIxT4f

以下是返回的形式。

{
  "_index" : "qiita",
  "_type" : "_doc",
  "_id" : "J32eLXYB4YEI6IRIxT4f",
  "_version" : 1,
  "_seq_no" : 1,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearchチュートリアル書いてみた",
    "description" : "チュートリアルです。みんな見てね。",
    "screen_name" : "mayoxmayo"
  }
}

如果想全部取出的话,请按照以下方式进行操作。

让我们尝试复制并执行以下文本。

GET qiita/_search

将以以下方式的形式进行归还。

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "qiita",
        "_type" : "_doc",
        "_id" : "2434",
        "_score" : 1.0,
        "_source" : {
          "title" : "アドベントカレンダーxx日目のタイトル",
          "description" : "どうも初めまして。xxと申します。",
          "screen_name" : "k-waragai"
        }
      },
      {
        "_index" : "qiita",
        "_type" : "_doc",
        "_id" : "J32eLXYB4YEI6IRIxT4f",
        "_score" : 1.0,
        "_source" : {
          "title" : "Elasticsearchチュートリアル書いてみた",
          "description" : "チュートリアルです。みんな見てね。",
          "screen_name" : "mayoxmayo"
        }
      }
    ]
  }
}

和以往不同,我使用了一个名为_search的工具进行了利用。

如果没有指定_id并忘记_id的情况下,该如何进行搜索呢?尝试使用常规的搜索方法。

6. 进行搜索

如果你想要查看k-waragai用户的文章,请按以下步骤操作:
复制并执行以下内容。

GET qiita/_search?q=screen_name:k-waragai

将返回以下形式的内容。

{
  "took" : 49,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.2199391,
    "hits" : [
      {
        "_index" : "qiita",
        "_type" : "_doc",
        "_id" : "2434",
        "_score" : 1.2199391,
        "_source" : {
          "title" : "アドベントカレンダーxx日目のタイトル",
          "description" : "どうも初めまして。xxと申します。",
          "screen_name" : "k-waragai"
        }
      }
    ]
  }
}

当需要进行关键词搜索时,可以按照以下方式进行指定。

GET qiita/_search?q=初めまして

现在我将详细介绍关于归还的细节。

key説明hits.total.value検索結果件数hits.total.relation検索結果方式(eq=等しい)hits.max_score検索結果の重み付けの最大値hits.hits._scoreヒット時のスコアリング

我们来试一试更复杂的搜索吧。

如果在描述中搜索不包含”开始”但包含”教程”的内容,应按以下方式描述。

GET qiita/_search
{
  "query": {
    "bool": { 
      "must": [
        {"match": {"description": "初め"}}
      ],
      "must_not": [
        {"match": {"description": "チュートリアル"}}
      ]
    }
  }
}

因为数据量较少,所以没有包含“教程”。

  "hits" : [
    {
      "_index" : "qiita",
      "_type" : "_doc",
      "_id" : "2434",
      "_score" : 1.2730759,
      "_source" : {
        "title" : "アドベントカレンダーxx日目のタイトル",
        "description" : "どうも初めまして。xxと申します。",
        "screen_name" : "k-waragai"
      }
    }
  ]

如果在Rails上使用的话

现在先简单地创建一个Rails应用程序就可以了。

本次将使用简单的配置,采用Rails5 + MySQL的组合。

我们将对结构进行如下修改。

ad_12.png

由于存在多个Dockerfile,我认为创建并分开目录会使其更易读。

准备Rails

准备用于Ruby的Dockerfile

这基本上就是符合官方标准的 Ruby 代码描述。

路径:dockerfiles/ruby/Dockerfile

FROM ruby:2.6.2

RUN apt-get update -qq && \
    apt-get install -y build-essential libpq-dev nodejs

RUN mkdir /app
WORKDIR /app

COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock

RUN bundle install
COPY . /app

2. 准备 Gemfile

由于对Rails6还有许多不了解的部分,所以我们将在Rails5上进行。

    https://rubygems.org/gems/rails/versions/5.2.4.4

路径:Gemfile

source 'https://rubygems.org'
gem 'rails', '~> 5.2', '>= 5.2.4.4'

当完成创建后,请生成Gemfile.lock文件。

ad_13.png

3. 修改compose文件

我们将修改现有的docker-compose.yml文件。

我正在添加用于mysql的服务定义和用于ruby的服务定义。

我还在Rails应用程序中传递和链接用于Elasticsearch的URL。

version: "3"
services:
  elasticsearch-v7.9.3:
    container_name: "elasticsearch"
    build:
      context: .
      dockerfile: ./dockerfiles/elasticsearch/Dockerfile
    environment:
      - discovery.type=single-node
      - bootstrap.memory_lock=true
      - logger.deprecation.level=debug
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    ports:
      - "9200:9200"
    volumes:
      - elasticsearch-v7.9.3-data:/usr/share/elasticsearch/data

  kibana-v7.9.3:
    image: docker.elastic.co/kibana/kibana-oss:7.9.3
    ports:
      - "5601:5601"
    restart: always
    environment:
      - "ELASTICSEARCH_HOSTS=http://elasticsearch:9200"

  database:
    container_name: mysql
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    ports:
      - "3306:3306"

  app:
    build:
      context: .
      dockerfile: ./dockerfiles/ruby/Dockerfile
    environment:
      ELASTICSEARCH_URL: http://elasticsearch:9200/
      MYSQL_HOST: database
    command: rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    links:
      - database
      - elasticsearch-v7.9.3

volumes:
  elasticsearch-v7.9.3-data:
    driver: local

4. 新建一个 Rails 项目

ad_14.png

如果那样做,就会变成熟悉的景象。

ad_15.png

5. 配置文件的修改 (Pinyin: de

我将进行数据库.yml的修改操作。

default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: database

development:
  <<: *default
  database: app_development

6. 建设

為了執行bundle install等操作,我們需要進行build。

我觉得把宝石之类的东西作为独立的卷进行持有也可以,但考虑到这次更新的频率并不是非常高,所以我们选择了最简配置。

ad_16.png

7. 创建数据库

ad_17.png

8. 启动docker-compose。

ad_18.png

当你访问 localhost:3000 并出现以下画面时,准备工作已完成。

ad_19.png

准备Elasticsearch

1. 对Gemfile进行添加

请将与Elasticsearch相关的Gem插入。请将以下3个Gem添加到Gemfile中。

# Elasticsearch関係
gem 'elasticsearch', '~> 7.10'
gem 'elasticsearch-rails', '~> 7.1', '>= 7.1.1'
gem 'elasticsearch-model', '~> 7.1', '>= 7.1.1'

2. 安装软件包。

请通过Ctrl+C终止已启动的进程,并输入以下命令。

ad_20.png

3. 模型的创建

ad_21.png
    migrationの変更
class CreateArticles < ActiveRecord::Migration[5.2]
  def change
    create_table :articles do |t|
      t.string :title, null: false, limit: 10, comment: "記事のタイトル"
      t.text   :description, null: false, comment: "記事の本文"
      t.string :screen_name, null: false, comment: "表示名"

      t.timestamps
    end
  end
end
    migrate
ad_22.png

4. 数据输入

我会准备大约三项适当的数据。

我自己使用了Seed进行了注入,但也可以从rails console进行注入。

Article.create(
  title: "犬の気持ち",
  description: "吾輩は犬である。名前はまだない。",
  screen_name: "k-waragai"
)

Article.create(
  title: "ねこのすべて",
  description: "猫はとても気まぐれです。気まぐれロマンティック。構って欲しい時にしか寄ってきません。ぴえん。",
  screen_name: "t-suzuki"
)

Article.create(
  title: "私VTuberになる",
  description: "どうも初めましてVTuberの酢飯マグロです。VTuberを始めて1年経って分かった5つの大事な事を紹介します。",
  screen_name: "m-sumeshi"
)

为了使用elasticsearch-rails,需要包含(include)它。

在Article的模型文件中添加Elasticsearch::Model的include。

class Article < ApplicationRecord
  include Elasticsearch::Model
end

通过添加这个,model.__elasticsearch__.method就可以使用,导入和搜索等操作会变得更容易。

在Elasticsearch中进行投入和查询

1. 连接至控制台

ad_23.png

2. 创建索引 d’index)

通过使用`create_index!`可以创建索引。
在进行详细的映射设置等操作时,最好事先定义好setting和mapping,然后根据定义进行输入。

这次我们将直接使用已经制作好的模型。

ad_24.png

我们来实际在 Kibana 中确认一下。

ad_25.png

目前已经制作了索引。

3. 数据输入

使用import即可将数据导入。非常简单吧。

ad_26.png

让我们实际通过 index/_search 来查看搜索结果。

ad_27.png

数据已经被正确录入了啊。

在Rails中,使用model.__elasticsearch__.search来查看这个。

Article.__elasticsearch__.search(version: true, query: { term: { id: 1 } }, size: 1).response.hits.hits.first

以类似的方式构建查询并进行搜索是可能的。

ad_28.png

4. 删除

我认为你应该已经明白了,可以使用Article.\_\_elasticsearch\_\_.delete\_index!来实现。

总结

由于Elasticsearch非常易于使用,所以请大家抓住机会去尝试一下。

明天再见。

广告
将在 10 秒后关闭
bannerAds