SpringBoot Elasticsearch6.8.5

es目录.png

Windwos Elasticsearch

Elasticsearch 基本介绍

全文搜索属于最常见的需求,开源的 Elasticsearch (以下简称 Elastic)是目前全文搜索引擎的首选。

Elasticsearch是一个开源的分布式、RESTful 风格的搜索和数据分析引擎,它的底层是开源库Apache Lucene。
 Lucene 可以说是当下最先进、高性能、全功能的搜索引擎库——无论是开源还是私有,但它也仅仅只是一个库。为了充分发挥其功能,你需要使用 Java 并将 Lucene 直接集成到应用程序中。 更糟糕的是,您可能需要获得信息检索学位才能了解其工作原理,因为Lucene 非常复杂。

Elastic 的底层是开源库 Lucene。但是,你没法直接用 Lucene,必须自己写代码去调用它的接口。Elastic 是 Lucene 的封装,提供了 REST API 的操作接口,开箱即用。

为了解决Lucene使用时的繁复性,于是Elasticsearch便应运而生。它使用 Java 编写,内部采用 Lucene 做索引与搜索,但是它的目标是使全文检索变得更简单,简单来说,就是对Lucene 做了一层封装,它提供了一套简单一致的 RESTful API 来帮助我们实现存储和检索。
 当然,Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎。 它可以被下面这样准确地形容:

  • 一个分布式的实时文档存储,每个字段可以被索引与搜索
  • 一个分布式实时分析搜索引擎
  • 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据
  • 可以快速地储存、搜索和分析海量数据

由于Elasticsearch的功能强大和使用简单,维基百科、卫报、Stack Overflow、GitHub等都纷纷采用它来做搜索。现在,Elasticsearch已成为全文搜索领域的主流软件之一。

Elastic 是java写的,需要 Java 的jdk环境,根据下方【版本手册】查看对应jdk版本。

推荐华为镜像快速下载https://mirrors.huaweicloud.com/elasticsearch/

官方选择下载https://www.elastic.co/cn/downloads/past-releases/#elasticsearch

所有版本手册https://www.elastic.co/guide/en/elasticsearch/reference/index.html

客户端https://www.elastic.co/guide/en/elasticsearch/client/index.html

Elasticsearch 6.8.5 单机安装

环境要求:jdk1.8(最低)、Elasticsearch 6.8.5

系统:Windwows

下载:elasticsearch-6.8.5.zip , 参考手册-6.8

安装:解压,找到bin\elasticsearch.bat,双击运行

访问:http://127.0.0.1:9200/

{
  "name" : "i1_C38J",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "_YG2A3LpSoOdh-wdLPOzlA",
  "version" : {
    "number" : "6.8.5",
    "build_flavor" : "default",
    "build_type" : "zip",
    "build_hash" : "78990e9",
    "build_date" : "2019-11-13T20:04:24.100411Z",
    "build_snapshot" : false,
    "lucene_version" : "7.7.2",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

以上显示效果说明已经安装好Elasticsearch

kibana6.8.5 可视化工具

注意: kibana版本必须和Elasticsearch版本一致,否则会出现不可预料的错误。

安装参考:https://www.elastic.co/guide/cn/kibana/current/windows.html

下载:kibana-6.8.5-windows-x86_64.zip) 解压。

**zip目录文件: **

.zip 整个包是独立的。默认情况下,所有的文件和目录都在 $KIBANA_HOME — 解压包时创建的目录下。这是非常方便的,因为您不需要创建任何目录来使用 Kibana,卸载 Kibana 只需要简单的删除 $KIBANA_HOME 目录。但还是建议修改一下配置文件和数据目录,这样就不会删除重要数据。

类型 描述 默认位置 设置
home Kibana home 目录或 $KIBANA_HOME 解压包时创建的目录
bin 二进制脚本,包括 kibana 启动 Kibana 服务和 kibana-plugin 安装插件。 $KIBANA_HOME\bin
config 配置文件包括 kibana.yml $KIBANA_HOME\config
data Kibana 和其插件写入磁盘的数据文件位置。 $KIBANA_HOME\data
optimize 编译过的源码。某些管理操作(如,插件安装)导致运行时重新编译源码。 $KIBANA_HOME\optimize
plugins 插件文件位置。每一个插件都一个单独的二级目录。 $KIBANA_HOME\plugins

配置系统环境变量:KIBANA_HOME=E:\Elasticsearch\kibana-6.8.5-windows-x86_64\bin

# 启动 kibana
.\bin\kibana.bat
# 日志:输出 log 到 STDOUT
# Ctrl-C 停止 Kibana

浏览器访问:http://localhost:5601 安装成功。

kibana 汉化:

从6.7版本开始,Kibana支持中文,无需再像之前那样下载汉化包,甚至自己进行翻译

打开config/kibana.yml,找到最后一行,去掉#,并将"en"改成"zh-CN"

#i18n.locale: "en"
i18n.locale: "zh-CN"

**重启kibana **

Springboot Elasticsearch 6.8.5

一、选择版本

Spring Data Elasticsearch

参考:https://docs.spring.io/spring-data/elasticsearch/docs/3.2.0.RC3/reference/html/#preface.versions

Spring Data Elasticsearch、Elasticsearch 对应版本

Spring Data Elasticsearch Elasticsearch
3.2.x 6.8.1
3.1.x 6.2.2
3.0.x 5.5.0
2.1.x 2.4.0
2.0.x 2.2.0
1.3.x 1.5.2

Spring Boot、Spring Data Elasticsearch、Elasticsearch 对应版本

Spring Data Release Train Spring Data Elasticsearch Elasticsearch Spring Boot
Neumann[1] 4.0.x[1] 7.6.2 2.3.x[1]
Moore 3.2.x 6.8.6 2.2.x
Lovelace 3.1.x 6.2.2 2.1.x
Kay[2] 3.0.x[2] 5.5.0 2.0.x[2]
Ingalls[2] 2.1.x[2] 2.4.0 1.5.x[2]

dome参考:https://github.com/spring-projects/spring-data-examples/tree/master/elasticsearch

Java Elasticsearch 客户端

官方推荐:https://www.elastic.co/guide/en/elasticsearch/client/index.html

二、Spring Data Elasticsearch

Spring Data Elasticsearch 默认使用 High Level REST Client

版本:springboot 2.0.5、Elasticsearch6.8.5、springboot data elasticsearch3.2.5

pom.xml

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-elasticsearch</artifactId>
    <version>3.2.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>6.8.5</version>
</dependency>

*.yml

spring:
  data:
    elasticsearch:
      repositories:
        enabled: true # 启用 ElasticsearchTemplate
      properties:
        path:
          logs: ./elasticsearch/log   # ES日志存储目录
          data: ./elasticsearch/data  # ES数据存储目录
      cluster-name: my-cluster        # ES集群名称,在elasticsearch.yml中配置 默 elasticsearch
      cluster-nodes: 127.0.0.1:9300   # ES集群节点 用逗号分隔 , java连接默9300,http连接默9200

实体类

@Data
@Document(indexName = "book_index", type = "book_type", indexStoreType = "fs", shards = 5, replicas = 1, refreshInterval = "-1")
public class BookEntity {
    @Id
    private String id;
    private String title;
    private String content;
    private int userId;
    private int weight;
}

Repository接口

@Component
public interface BookRepository extends ElasticsearchRepository<BookEntity, String> {
}

controller层

package com.dist.controller;

import com.dist.dao.BookRepository;
import com.dist.entity.BookEntity;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.web.bind.annotation.*;

import static org.elasticsearch.index.query.QueryBuilders.*;

/**
 * @author*@*.com.cn
 * @data 2020/07/17 11:41
 */
@RestController
@Api(tags = {"BookElasticsearchController"}, description = "全文检索")
public class BookElasticsearchController {

    @Autowired
    ElasticsearchTemplate elasticsearchTemplate;

    @Autowired
    BookRepository bookRepository;

    @ApiOperation(value = "添加索引", httpMethod = "POST")
    @PostMapping(value = "v1/book/add/{id}")
    public Object addbook(@ApiParam(defaultValue = "50") @PathVariable String id) {
        //创建索引
        // 1、直接用名称创建索引
        //boolean indexRes = elasticsearchTemplate.createIndex("book_es");
        // 2、填入class对象创建索引
        //boolean indexRes = elasticsearchTemplate.createIndex(BookEntity.class);
        //System.out.println("======创建索引结果:" + indexRes + "=========");

        BookEntity bookEntity = new BookEntity();
        bookEntity.setId(id);
        bookEntity.setTitle("浣溪沙");
        bookEntity.setContent("宋·李清照 莫许杯深琥珀浓,未成沉醉意先融。疏钟已应晚来风。瑞脑香消魂梦断");
        bookEntity.setUserId(51);
        bookEntity.setWeight(100);

        IndexQuery indexQuery = new IndexQueryBuilder()
                .withId(bookEntity.getId())
                .withObject(bookEntity)
                .build();
        String index = elasticsearchTemplate.index(indexQuery);
        //BookEntity document = bookRepository.save(bookEntity);
        return index;
    }

    @ApiOperation(value = "查询全部内容", httpMethod = "GET")
    @GetMapping(value = "v1/book/srarch/all")
    public Object srarch() {
        return bookRepository.findAll();
    }

    @ApiOperation(value = "根据id查询内容", httpMethod = "GET")
    @GetMapping(value = "v1/book/srarch/id")
    public Object srarch(@ApiParam(defaultValue = "50") @RequestParam String id) {
        return bookRepository.findById(id);
    }

    @ApiOperation(value = "根据id更新内容", httpMethod = "PUT")
    @PutMapping(value = "v1/book/srarch/updete")
    public Object updete(@ApiParam(defaultValue = "50") @RequestParam String id) {
        BookEntity bookEntity = new BookEntity();
        bookEntity.setId(id);
        bookEntity.setTitle("浣溪沙2");
        bookEntity.setContent("宋·李清照 莫许杯深琥珀浓,未成沉醉意先融。疏钟已应晚来风。瑞脑香消魂梦断");
        bookEntity.setUserId(55);
        bookEntity.setWeight(102);
        return bookRepository.save(bookEntity);
    }

    @ApiOperation(value = "单字符串全文模糊查询Ex", httpMethod = "GET")
    @GetMapping(value = "v1/book/srarch/ex")
    public Object srarchEx(@ApiParam(value = "查询内容", defaultValue = "浣溪沙") @RequestParam String content,
                         @ApiParam(value = "当前页", defaultValue = "0") @RequestParam int page,
                         @ApiParam(value = "显示多少条", defaultValue = "20") @RequestParam int size) {

        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.queryStringQuery(content)).withPageable(PageRequest.of(page, size)).build();
        return bookRepository.search(searchQuery);
    }

    @ApiOperation(value = "多字段的匹配查询Ex", httpMethod = "GET")
    @GetMapping(value = "v1/book/srarch/queryBuilder")
    public Object srarchQueryBuilder(@ApiParam(value = "查询内容", defaultValue = "浣溪沙") @RequestParam String title) {

        MultiMatchQueryBuilder queryBuilder = multiMatchQuery(title, "title", "content");
        return bookRepository.search(queryBuilder);
    }

    @ApiOperation(value = "单字符串全文模糊查询", notes = "查询全部字段内容", httpMethod = "GET")
    @GetMapping(value = "v1/book/srarch")
    public Object srarch(@ApiParam(value = "查询内容", defaultValue = "浣溪沙") @RequestParam String content,
                         @ApiParam(value = "当前页", defaultValue = "0") @RequestParam int page,
                         @ApiParam(value = "显示多少条", defaultValue = "20") @RequestParam int size) {
        //使用queryStringQuery完成单字符串查询
        //单字符串默认模糊查询,默认排序。将从所有字段中查找包含传来的content分词后字符串的数据集
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.queryStringQuery(content)).withPageable(PageRequest.of(page, size)).build();
        return elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
    }

    @ApiOperation(value = "某字段字符串模糊查询", notes = "将从所有字段中查找包含传来的content分词后字符串的数据集", httpMethod = "GET")
    @GetMapping(value = "v1/book/srarch/matchQuery")
    public Object srarchMatchQuery(@ApiParam(value = "查询内容", defaultValue = "浣溪沙") @RequestParam String content,
                                   @ApiParam(value = "当前页", defaultValue = "0") @RequestParam int page,
                                   @ApiParam(value = "显示多少条", defaultValue = "20") @RequestParam int size) {
        //某字段(content)字符串模糊查询
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("content", content)).withPageable(PageRequest.of(page, size)).build();
        return elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
    }

    @ApiOperation(value = "短语匹配", notes = "短语必须是连续的 不知归路 不归路", httpMethod = "GET")
    @GetMapping(value = "v1/book/srarch/PhraseQuery")
    public Object srarchPhraseQuery(@ApiParam("查询内容") @RequestParam String content,
                                    @ApiParam(value = "当前页", defaultValue = "0") @RequestParam int page,
                                    @ApiParam(value = "显示多少条", defaultValue = "20") @RequestParam int size) {

        // PhraseMatch查询,短语匹配,单字段对某短语进行匹配查询,短语分词的顺序会影响结果
        //类似于数据库里的 %落日熔金%
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchPhraseQuery("content", content)).withPageable(PageRequest.of(page, size)).build();
        return elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
    }

    @ApiOperation(value = "完全匹配查询", notes = "最严格的匹配,不进行分词", httpMethod = "GET")
    @GetMapping(value = "v1/book/srarch/TermQuery")
    public Object srarchTermQuery(@ApiParam(value = "id", defaultValue = "5") @RequestParam int userId,
                                  @ApiParam(value = "当前页", defaultValue = "0") @RequestParam int page,
                                  @ApiParam(value = "显示多少条", defaultValue = "10") @RequestParam int size) {
        //term一般适用于做过滤器filter的情况,譬如我们去查询title中包含“浣溪沙”且userId=1时,那么就可以用termQuery(“userId”, 1)作为查询的filter
        //不对传来的值分词,去找完全匹配的
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("userId", userId)).withPageable(PageRequest.of(page, size)).build();
        return elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
    }

    @ApiOperation(value = "多字段的匹配查询", httpMethod = "GET")
    @GetMapping(value = "v1/book/srarch/MultiMatchQuery")
    public Object srarchMultiMatchQuery(@ApiParam("查询内容") @RequestParam String title,
                                        @ApiParam(value = "当前页", defaultValue = "0") @RequestParam int page,
                                        @ApiParam(value = "显示多少条", defaultValue = "10") @RequestParam int size) {

        //MultiMatchQuery: 多字段匹配 "title","content" ,只要任何一个字段包括该字符串即可
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.multiMatchQuery(title, "title", "content"))
                .withPageable(PageRequest.of(page, size))
                .build();

        //MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery(title, "title", "content");
        //构建查询对象
        /*SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(multiMatchQuery)
                .withIndices("book_es")  //索引名
                .withPageable(PageRequest.of(page, size, new Sort(Sort.Direction.DESC, "id")))
                .build();*/
        //执行查询
        return elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
    }

    @ApiOperation(value = "多字段合并查询", httpMethod = "GET")
    @GetMapping(value = "v1/book/srarch/BoolQuery")
    public Object srarchBoolQuery(@ApiParam(value = "userId", defaultValue = "2") @RequestParam String userId,
                                  @ApiParam(value = "weight", defaultValue = "14") @RequestParam String weight,
                                  @ApiParam(value = "title", defaultValue = "浣溪沙") @RequestParam String title) {
        //boolQuery 可以设置多个条件的查询方式,用来组合多个Query,组合方式有四种:must,mustnot,filter,should
        /*must代表返回的文档必须满足must子句的条件,会参与计算分值;
        filter代表返回的文档必须满足filter子句的条件,但不会参与计算分值;
        should代表返回的文档可能满足should子句的条件,也可能不满足,有多个should时满足任何一个就可以,通过minimum_should_match设置至少满足几个。
        mustnot代表必须不满足子句的条件。*/
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.boolQuery().must(termQuery("userId", userId))
                .should(rangeQuery("weight").lt(weight)).must(matchQuery("title", title))).build();
        return elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
    }

    @ApiOperation(value = "删除索引", httpMethod = "DELETE")
    @DeleteMapping(value = "v1/book/delete")
    public void deleteIndex(@ApiParam("id") @RequestParam String id) {

        //删除索引
        BookEntity bookEntity = new BookEntity();
        bookEntity.setId(id);

        //bookRepository.delete(bookEntity);
        //根据id删除
        bookRepository.deleteById(id);
        //删除所有
        //bookRepository.deleteAll();
    }

    @ApiOperation(value = "删除所有索引", httpMethod = "DELETE")
    @DeleteMapping(value = "v1/book/delete/all")
    public void deleteAllIndex() {
        //删除所有
        bookRepository.deleteAll();
    }

}

InitBookData 初始化数据

/**
 * Email: *.com.cn
 * Desc:只初始化一次测试数据
 */
@Component
public class InitBookData {

    @Autowired
    BookRepository bookRepository;

    @PostConstruct
    public void init() {
        //只初始化一次
        Iterable<BookEntity> posts = bookRepository.findAll();
        if (posts.iterator().hasNext()) {
            return;
        }
        for (int i = 0; i < 40; i++) {
            BookEntity book = new BookEntity();
            book.setTitle(getTitle().get(i));
            book.setContent(getContent().get(i));
            book.setWeight(i);
            book.setUserId(i % 10);
            bookRepository.save(book);
        }
    }

    private List<String> getTitle() {
        List<String> list = new ArrayList<>();
        list.add("《如梦令·常记溪亭日暮》");
        list.add("《醉花阴·薄雾浓云愁永昼》");
        list.add("《声声慢·寻寻觅觅》");
        list.add("《永遇乐·落日熔金》");
        list.add("《如梦令·昨夜雨疏风骤》");
        list.add("《渔家傲·雪里已知春信至》");
        list.add("《点绛唇·蹴[1]罢秋千》");
        list.add("《点绛唇·寂寞深闺》");
        list.add("《蝶恋花·泪湿罗衣脂粉满》");
        list.add("《蝶恋花 离情》");
        list.add("《浣溪沙》");
        list.add("《浣溪沙》");
        list.add("《浣溪沙》");
        list.add("《浣溪沙》");
        list.add("《浣溪沙》");
        list.add("《减字木兰花·卖花担上》");
        list.add("《临江仙·欧阳公作《蝶恋花》");
        list.add("《临江仙·庭院深深深几许》");
        list.add("《念奴娇·萧条庭院》");
        list.add("《菩萨蛮·风柔日薄春犹早》");
        list.add("《菩萨蛮·归鸿声断残云碧》");
        list.add("《武陵春·风住尘香花已尽》");
        list.add("《一剪梅·红藕香残玉蕈秋》");
        list.add("《渔家傲·天接云涛连晓雾》");
        list.add("《鹧鸪天·暗淡轻黄体性柔》");
        list.add("《鹧鸪天·寒日萧萧上锁窗》");
        list.add("《一剪梅·红藕香残玉簟秋》");
        list.add("《如梦令·常记溪亭日暮》");
        list.add("《浣溪沙》");
        list.add("《浣溪沙》");
        list.add("《浣溪沙》");
        list.add("《蝶恋花·泪湿罗衣脂粉满》");
        list.add("《蝶恋花·暖日晴风初破冻》");
        list.add("《鹧鸪天·寒日萧萧上锁窗》");
        list.add("《醉花阴·薄雾浓云愁永昼》");
        list.add("《鹧鸪天·暗淡轻黄体性柔》");
        list.add("《蝶恋花·永夜恹恹欢意少》");
        list.add("《浣溪沙》");
        list.add("《浣溪沙》");
        list.add("《如梦令·谁伴明窗独坐》");
        return list;
    }

    private List<String> getContent() {
        List<String> list = new ArrayList<>();
        list.add("初中 宋·李清照 常记溪亭日暮,沉醉不知归路,兴尽晚回舟,误入藕花深处。争渡,争渡");
        list.add("重阳节 宋·李清照 薄雾浓云愁永昼,瑞脑消金兽。佳节又重阳,玉枕纱厨,半夜凉初透。东");
        list.add("闺怨诗 宋·李清照 寻寻觅觅,冷冷清清,凄凄惨惨戚戚。乍暖还寒时候,最难将息。三杯两");
        list.add("元宵节 宋·李清照 落日熔金,暮云合璧,人在何处。染柳烟浓,吹梅笛怨,春意知几许。元");
        list.add("婉约诗 宋·李清照 昨夜雨疏风骤,浓睡不消残酒,试问卷帘人,却道海棠依旧。知否,知否");
        list.add("描写梅花 宋·李清照 雪里已知春信至,寒梅点缀琼枝腻,香脸半开娇旖旎,当庭际,玉人浴出");
        list.add(" 宋·李清照 蹴罢秋千,起来慵整纤纤手。露浓花瘦,薄汗轻衣透。见客入来,袜刬金");
        list.add("闺怨诗 宋·李清照 寂寞深闺,柔肠一寸愁千缕。惜春春去。几点催花雨。倚遍阑干,只是无");
        list.add("婉约诗 宋·李清照 泪湿罗衣脂粉满。四叠阳关,唱到千千遍。人道山长水又断。萧萧微雨闻");
        list.add("描写春天 宋·李清照 暖雨晴风初破冻,柳眼梅腮,已觉春心动。酒意诗情谁与共?泪融残粉花");
        list.add("寒食节 宋·李清照 淡荡春光寒食天,玉炉沈水袅残烟,梦回山枕隐花钿。海燕未来人斗草,");
        list.add(" 宋·李清照 髻子伤春慵更梳,晚风庭院落梅初,淡云来往月疏疏,玉鸭薰炉闲瑞脑,");
        list.add(" 宋·李清照 莫许杯深琥珀浓,未成沉醉意先融。疏钟已应晚来风。瑞脑香消魂梦断,");
        list.add("闺怨诗 宋·李清照 小院闲窗春已深,重帘未卷影沉沉。倚楼无语理瑶琴,远岫出山催薄暮。");
        list.add("爱情诗 宋·李清照 绣幕芙蓉一笑开,斜偎宝鸭亲香腮,眼波才动被人猜。一面风情深有韵,");
        list.add("描写春天 宋·李清照 卖花担上,买得一枝春欲放。泪染轻匀,犹带彤霞晓露痕。怕郎猜道,奴");
        list.add("》 宋·李清照 欧阳公作《蝶恋花》,有“深深深几许”之句,予酷爱之。用其语作“庭");
        list.add("描写梅花 宋·李清照 庭院深深深几许,云窗雾阁春迟,为谁憔悴损芳姿。夜来清梦好,应是发");
        list.add("寒食节 宋·李清照 萧条庭院,又斜风细雨,重门须闭。宠柳娇花寒食近,种种恼人天气。险");
        list.add("思乡诗 宋·李清照 风柔日薄春犹早,夹衫乍著心情好。睡起觉微寒,梅花鬓上残。故乡何处");
        list.add("描写春天 宋·李清照 归鸿声断残云碧,背窗雪落炉烟直。烛底凤钗明,钗头人胜轻。角声催晓");
        list.add("闺怨诗 宋·李清照 风住尘香花已尽,日晚倦梳头。物是人非事事休,欲语泪先流。闻说双溪");
        list.add(" 宋·李清照 红藕香残玉蕈秋,轻解罗裳,独上兰舟。云中谁寄锦书来?雁字回时,月");
        list.add("豪放诗 宋·李清照 天接云涛连晓雾。星河欲转千帆舞。仿佛梦魂归帝所。闻天语。殷勤问我");
        list.add("描写花 宋·李清照 暗淡轻黄体性柔。情疏迹远只香留。何须浅碧深红色,自是花中第一流。");
        list.add("描写秋天 宋·李清照 寒日萧萧上琐窗,梧桐应恨夜来霜。酒阑更喜团茶苦,梦断偏宜瑞脑香。");
        list.add("闺怨诗 宋·李清照 红藕香残玉簟秋。轻解罗裳,独上兰舟。云中谁寄锦书来?雁字回时,月");
        list.add(" 宋·李清照 常记溪亭日暮。沈醉不知归路。兴尽晚回舟,误入藕花深处。争渡。争渡");
        list.add(" 宋·李清照 莫许杯深琥珀浓。未成沈醉意先融。已应晚来风。瑞脑香消魂梦断,");
        list.add(" 宋·李清照 小院闲窗春色深。重帘未卷影沈沈。倚楼无语理瑶琴。远岫出山催薄暮,");
        list.add(" 宋·李清照 淡荡春光寒食天。玉炉沈水袅残烟。梦回山枕隐花钿。海燕未来人斗草,");
        list.add(" 宋·李清照 泪湿罗衣脂粉满。四叠阳关,唱到千千遍。人道山长山又断。萧萧微雨闻");
        list.add(" 宋·李清照 暖日晴风初破冻。柳眼眉腮,已觉春心动。酒意诗情谁与共。泪融残粉花");
        list.add(" 宋·李清照 寒日萧萧上锁窗。梧桐应恨夜来霜。酒阑更喜团茶苦,梦断偏宜瑞脑香。");
        list.add(" 宋·李清照 薄雾浓云愁永昼。瑞脑消金兽。佳节又重阳,玉枕纱厨,半夜凉初透。东");
        list.add(" 宋·李清照 暗淡轻黄体性柔。情疏迹远只香留。何须浅碧深红色,自是花中第一流。");
        list.add(" 宋·李清照 永夜恹恹欢意少。空梦长安,认取长安道。为报今年春色好。花光月影宜");
        list.add(" 宋·李清照 髻子伤春慵更梳。晚风庭院落梅初。淡云来往月疏疏。玉鸭熏炉闲瑞脑,");
        list.add(" 宋·李清照 绣面芙蓉一笑开。斜飞宝鸭衬香腮。眼波才动被人猜。一面风情深有韵,");
        list.add(" 宋·李清照 谁伴明窗独坐,我共影儿俩个。灯尽欲眠时,影也把人抛躲。无那,无那");
        return list;
    }

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266