原文:Elasticsearch入门教程(三):Elasticsearch索引&映射

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

索引概念简介

通常说的索引有两种词性,名称和动词。

  • 动词索引indexing,索引一个文档,表示把一个文档存储到索引Index里,可以用来查询和检索,es采用倒排索引
  • 名词索引index,简单的理解成关系型数据库中的数据库的概念

索引的命名必须是全部小写,不能以下划线开头.

创建索引

创建索引可以显式创建,也可以隐式创建。

  • 显式创建:在关系型数据库中,需要先建数据库,在创建数据库时可以指定一些配置,如字符编码,数据库引擎等,创建表时需要指定表都包含哪些列,每个列的数据类型等,在在Elasticsearch中创建数据库(索引)和创建表(映射)是一步完成的,显式创建需要在创建时指定对索引的一些配置,需要列举出索引包含的字段,也就是所谓的映射Mapping
  • 隐式操作:隐式操作的方式是直接向索引中插入一条文档即可,es在插入的时候会判断索引是否存在,如果不存在,系统会根据文档包含的字段作为索引的映射,对索引的一些配置采用默认的配置来创建出来索引,创建索引的过程是es在后台默默的实现的。

显式创建可以根据具体情况对索引进行配置,而且对于中文分词es是默认采用的分词是适合英文并适合中文的,可以在创建索引的时候自己指定分词器。

ES支持的数据类型

  • text 文本类型,text类型如果不显示指定映射的字段属性,默认是使用标准分词器进行分词,一般数据类型是text要么显示指定分词器,要么不分词,一般不使用默认的分词器(除非文本是纯英文)
  • keyword : 如果数组中的值是字符串,最好使用keyword, 它不会对字符串进行分词
  • date 支持的格式有:可以通过format定义日期的数据格式,也支持毫秒数
  • boolean
  • float
  • double
  • byte
  • short
  • integer
  • long
  • object
  • nested : 嵌套对象, 用于数组中的元素是对象的[{}, {}]
  • ip 即支持ipv4也支持ipv6
  • completion
  • binary
  • geo-point: 支持经纬度存储和距离范围检索
  • geo-shape:支持任意图形范围的检索,例如矩形和平面多边形

注意:不同的数据类型索引的方式有稍许不同,如date何text类型不一样,date采用精确匹配,text采用全文检索方式。对于数组,es并没有专门的数组类型。任何域都可以包含0、1或者多个值,就像全文域分析得到多个词条。这暗示 数组中所有的值必须是相同数据类型的。

映射mappings

映射就是创建索引时指定都包含哪些字段以及字段的数据类型、分词器等一些设置。

字段设置参数

  • “type”: “text”, // 指定字段的数据类型
  • “analyzer”:”ik _max_word”, //指定分词器的名称,即可用使用内置的分词器也可以使用第三方分词器
    • 默认standard,
    • 内置的分析器有whitespace 、 simple和english
    • 第三方分词器:ik分词器 包括ik_max_word和ik_smart,ik_max_word:会将文本做最细粒度的拆分;尽可能多的拆分出词语 ,ik_smart:会做最粗粒度的拆分;已被分出的词语将不会再次被其它词语占有
  • “search_analyzer”:”ik _max_word” // 指定查询的分词器,默认和analyzer保持一致,一般分词器和查询分词器要保持一致
  • “properties”: {}, // 当数据类型是object时,需要具体指定内部对象对应的字段
  • “format”: “yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis” // 格式化,一般用于指定日期类型的格式
  • “dynamic”: “strict” 动态映射配置,当文档中发现新字段时应该如何处理, 可以用在根 object 或任何 object 类型的字段上,你可以将 dynamic 的默认值设置为 strict , 而只在指定的内部对象中开启它
    • true: 默认值,动态添加新的字段
    • false: 忽略新的字段
    • strict: 如果遇到新字段抛出异常,如果Elasticsearch是作为重要的数据存储,可能就会期望遇到新字段就会抛出异常,这样能及时发现问题。
  • dynamic_templates 动态模板:为满足条件的字段做统一映射,可以通过字段名称或者字段类型来匹配指定的映射规则,每个模板都有一个名称,你可以用来描述这个模板的用途, 一个mapping来指定映射应该怎样使用,以及至少一个参数 (如 match) 来定义这个模板适用于哪个字段。

    模板按照顺序来检测;第一个匹配的模板会被启用

    • match 参数只匹配字段名称
    • match_mapping_type 允许你应用模板到特定类型的字段上,就像有标准动态映射规则检测的一样
  • “fielddata”:boolean //针对分词字段,参与排序或聚合时能提高性能,默认是false,false是不允许聚合操作的
  • “boost”:1.23 // 权重:字段级别的分数加权,指定字段在搜索时所占的权重,所占的百分比
  • “fields”:{“raw”:{“type”:”keyword”}} //可以对一个字段提供多种索引模式,同一个字段的值,一个分词,一个不分词,应用场景:即可以用于对字符串进行字符排序,也可以全文索引,排序时使用字段.raw来引用排序字段
  • “index”: “analyzed”, // 指定文本类型的字段是否分词、是否存储该字段的值(在新版本中index值为boolean类型,语意也发生了变化,TODO待更新),有三个值:
    • analyzed:首先分析字符串,然后索引(存储)它。换句话说,以全文索引这个域(也就是说即分词,又存储字段的值,即可以通过全文检索的方式对该字段进行搜索)
    • not_analyzed:索引(存储)这个域,所以它能够被搜索,但索引的是精确值。不会对它进行分析(不对字段的值进行分词,而是完整的存储该值,所以只能通过精确值才能搜索出来,即完全匹配,相当于sql中的等号=的作用)
    • no:不索引这个域。这个域不会被搜索到(对该字段不分词,也不存储,相当于没有这个字段一样???)
  • “store”:false//是否单独设置此字段的是否存储而从_source字段中分离,默认是false,只能搜索,不能获取值
  • “doc_values”:false//对not_analyzed字段,默认都是开启,分词字段不能使用,对排序和聚合能提升较大性能,节约内存
  • “ignore_above”:100 //超过100个字符的文本,将会被忽略,不被索引
  • “include_in_all”:ture//设置是否此字段包含在_all字段中,默认是true,除非index设置成no选项
  • “index_options”:”docs”//4个可选参数docs(索引文档号) ,freqs(文档号+词频),positions(文档号+词频+位置,通常用来距离查询),offsets(文档号+词频+位置+偏移量,通常被使用在高亮字段)分词字段默认是position,其他的默认是docs
  • “norms”:{“enable”:true,”loading”:”lazy”}//分词字段默认配置,不分词字段:默认{“enable”:false},存储长度因子和索引时boost,建议对需要参与评分字段使用 ,会额外增加内存消耗量
  • “null_value”:”NULL”//设置一些缺失字段的初始化值,只有string可以使用,分词字段的null值也会被分词
  • “position_increament_gap”:0//影响距离查询或近似查询,可以设置在多值字段的数据上火分词字段上,查询时可指定slop间隔,默认值是100
  • “similarity”:”BM25”//默认是TF/IDF算法,指定一个字段评分策略,仅仅对字符串型和分词类型有效
  • “term_vector”:”no”//默认不存储向量信息,支持参数yes(term存储),with_positions(term+位置),with_offsets(term+偏移量),with_positions_offsets(term+位置+偏移量) 对快速高亮fast vector highlighter能提升性能,但开启又会加大索引体积,不适合大数据量用

ik分词器 https://github.com/medcl/elasticsearch-analysis-ik 支持自定义热词配置(如 香菇 蓝瘦 帅的一逼 等)

  1. // 默认standard,内置的分析器有whitespace 、 simple 和 english
  2. // ik支持两种分词器:ik_max_word,ik_smart
  3. // 分析器:用于测试分词的数据
  4. GET /_analyze
  5. {
  6. "analyzer" : "ik_max_word",
  7. "text": "美国留给伊拉克的是个烂摊子吗"
  8. }
  9.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

settings设置

settings用于设置索引的分片数量、副本数量、默认的分词器等,Elasticsearch 提供了优化好的默认配置。 除非你理解这些配置的作用并且知道为什么要去修改,否则不要随意修改。

  • “number_of_shards” : 5, // 每个索引的主分片数,默认值是 5 。这个配置在索引创建后不能修改。
  • “number_of_replicas” : 1, // 每个主分片的副本数,默认值是 1 。对于活动的索引库,这个配置可以随时修改。
  • “analysis” : { “analyzer” : { “ik” : { “tokenizer” : “ik_ max_word” } } }
  1. // 创建只有 一个主分片,没有副本的小索引:
  2. PUT /my_temp_index
  3. {
  4. "settings": {
  5. "number_of_shards" : 1,
  6. "number_of_replicas" : 0
  7. }
  8. }
  9. // 用update-index-settings API 动态修改副本数:
  10. PUT /my_temp_index/_settings
  11. {
  12. "number_of_replicas": 1
  13. }
  14.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

aliases别名

索引别名就像一个快捷方式或软连接,或者是一个指向,都是最终指的同一个东西,别名 带给我们极大的灵活性,允许我们做下面这些:

  • 在运行的集群中可以无缝的从一个索引切换到另一个索引
  • 给多个索引分组 (例如, last_three_months)
  • 给索引的一个子集创建 视图

有两种方式管理别名: _alias用于单个操作, _aliases用于执行多个原子级操作。

Mapping一旦创建是不允许修改字段的数据类型的,为了防止以后有可能修改索引的情况,刚开始创建索引时最好就为该索引创建一个别名,然后在程序中直接使用别名,而不使用真实的索引名称。

如果后面需要要修改映射,可以再创建一个新的索引,然后把之前索引里的数据导入到新创建的索引里, 为新索引增加一个别名,将别名从老索引中移除,这样应用程序仍然使用的是别名,而这个别名已经指向了新的索引,这样就达到了不修改索引名而修改索引的目的。

  1. // 0. 创建索引(age的类型为long)
  2. PUT /school_v1
  3. {
  4. "mappings": {
  5. "students": {
  6. "properties": {
  7. "name": { "type": "text" },
  8. "age": {"type": "long"}
  9. }
  10. }
  11. }
  12. }
  13. // 1. 为索引创建一个别名
  14. PUT /school_v1/_alias/school
  15. // 查看别名指向的索引
  16. GET /*/_alias/school
  17. // 查询索引对应的别名
  18. GET /school_v1/_alias/*
  19. // 2.创建一个新的索引,名字不能和之前的不一样,这次将age的数据类型改为short
  20. PUT /school_v2
  21. {
  22. "mappings": {
  23. "students": {
  24. "properties": {
  25. "name": { "type": "text" },
  26. "age": {"type": "short"}
  27. }
  28. }
  29. }
  30. }
  31. // 3.迁移数据:将之前的索引里的文档迁移到新的索引上
  32. // 先将数据批量查询出来,然后批量插入
  33. GET /school/students/_search?scroll=1m
  34. POST /schools/students/_bulk
  35. {"index": {"_id": 1}}
  36. {"name": "张三","age": 27}
  37. {"index": {"_id": 2}}
  38. {"name": "小明","age": 28}
  39. GET /schools/students/_search
  40. // 4.为新索引增加别名,别名名称为老索引名称,这样系统可以直接使用老索引的名称来操作新索引
  41. POST /_aliases
  42. {
  43. "actions": [
  44. {
  45. "add": { "index": "school_v2", "alias": "school"},
  46. "remove": { "index": "school_v1", "alias": "school"}
  47. }
  48. ]
  49. }
  50. GET /school/students/_search
  51.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

别名就是索引的另一个名字,就像人的姓名和笔名一样,都是指向的同一个人,可以通过POST /_aliases 路径对别名进行add、remove操作

TIP: 在你的应用中使用别名而不是索引名。然后你就可以在任何时候重建索引。别名的开销很小,应该广泛使用。

索引操作

创建索引

PUT /{index}

  1. // 注意:当前创建的索引的动态映射配置根对象是不允许添加新字段的,动态映射类型为严格类型,但是内部对象是允许添加新字段的
  2. PUT /shop_v1
  3. {
  4. "aliases": {
  5. "shop": {}
  6. },
  7. "settings" : {
  8. "number_of_shards" : 5,
  9. "number_of_replicas" : 1,
  10. "refresh_interval": "1s",
  11. "analysis" : {
  12. "analyzer" : {
  13. "ik" : {
  14. "tokenizer" : "ik_max_word"
  15. }
  16. }
  17. }
  18. },
  19. "mappings": {
  20. "goods": {
  21. "dynamic": "strict",
  22. "dynamic_templates":[
  23. { "date": {
  24. "match": "*_date",
  25. "match_mapping_type": "date",
  26. "mapping": {
  27. "type": "date",
  28. "format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
  29. }
  30. }},
  31. { "ik": {
  32. "match": "*",
  33. "match_mapping_type": "string",
  34. "mapping": {
  35. "type": "text",
  36. "analyzer": "ik_max_word",
  37. "search_analyzer": "ik_max_word"
  38. }
  39. }}
  40. ],
  41. "properties": {
  42. "name": {
  43. "type": "text",
  44. "analyzer": "ik_max_word",
  45. "search_analyzer": "ik_max_word"
  46. },
  47. "price": {
  48. "type": "double"
  49. },
  50. "quantity": {
  51. "type": "integer"
  52. },
  53. "colors": {
  54. "type": "keyword"
  55. },
  56. "is_discount": {
  57. "type": "boolean"
  58. },
  59. "create_date": {
  60. "type": "date",
  61. "format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
  62. },
  63. "ip_addr": {
  64. "type": "ip"
  65. },
  66. "location": {
  67. "type": "geo_point",
  68. "lat_lon": true
  69. },
  70. "merchant": {
  71. "type": "object",
  72. "dynamic": true,
  73. "properties": {
  74. "id": { "type": "long" },
  75. "shop_name": { "type": "text" }
  76. }
  77. },
  78. "cpu": {
  79. "type": "text",
  80. "fields": {
  81. "keyword": {
  82. "type": "keyword",
  83. "ignore_above": 256
  84. }
  85. }
  86. }
  87. }
  88. }
  89. }
  90. }
  91.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

refresh_interval:索引刷新时间间隔,一个持续时间值, 例如 1s(1 秒) 或 2m(2 分钟)。 一个绝对值1表示的是1毫秒 –无疑会使你的集群陷入瘫痪, -1:表示关闭刷新, 默认为一秒,如果索引了一个文档然后立即尝试搜索它,但却没有搜到,可能是还没有到间隔时间,还没有刷新

  • 查看所有索引 GET /_cat/indices?v&pretty

  • 查看某个索引 GET /{index}

  • 删除索引单个索引 DELETE /{index}

  • 删除所有索引 DELETE /_all 或者 DELETE /*

  • 删除多个索引: DELETE /index1,index2 或者 DELETE /index*

  • 查看索引的映射 GET /{index}/_mapping

  • 查看某个索引的某个类型的映射 GET /{index}/_mapping/{type}

  • 映射添加新字段 PUT /{index}/_mapping/{type}

  1. PUT /shop/_mapping/goods
  2. {
  3. "properties": {
  4. "params": {
  5. "type": "nested",
  6. "properties": {
  7. "id": { "type": "long" },
  8. "label": { "type": "text" },
  9. "value": { "type": "text" }
  10. }
  11. }
  12. }
  13. }
  14.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  1. // 插入一条文档
  2. POST /shop/goods
  3. {
  4. "name": "【特别尺码】女装 棉混纺休闲针织衫(长袖) 407767 优衣库UNIQLO",
  5. "price": 149.00,
  6. "quantity": 100,
  7. "colors": ["乳白色", "红色", "黄色"],
  8. "is_discount": true,
  9. "create_date": "2018-01-31 12:10:30",
  10. "ip_addr": "192.168.1.1",
  11. "location": "41.12,-71.34",
  12. "merchant": {
  13. "id": 1111,
  14. "shop_name": "优衣库官方旗舰店"
  15. },
  16. "params": [
  17. {"id": 1, "label":"货号", "value": "7525001123"},
  18. {"id": 2, "label":"品牌", "value": "Cache Cache"}
  19. ]
  20. }
  21.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

查询文档 /{index}/{type}/_search

  1. GET /shop/goods/_search
  2.  
    • 1

修改索引

  • 新增字段
  • 修改字段的数据类型
  1. ```
  2. // 创建索引
  3. PUT /school
  4. {
  5. "mappings": {
  6. "students": {
  7. "properties": {
  8. "name": { "type": "text" },
  9. "age": {"type": "long"}
  10. }
  11. }
  12. }
  13. }
  14. // 插入一条文档
  15. PUT /school/students/1
  16. {
  17. "name": "张三",
  18. "age": 27
  19. }
  20. // 查询映射
  21. GET school/_mapping/students
  22. // 添加文档,增加一个新字段height身高
  23. PUT /school/students/2
  24. {
  25. "name": "小明",
  26. "age": 28,
  27. "height": 1.80
  28. }
  29. GET school/_mapping/students
  30. // 查看映射可以看到自动将height作为float类型添加到映射里面
  31. "height": {"type": "float"}
  32.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

重新索引

尽管可以增加新的类型到索引中,或者增加新的字段到类型中,但是不能添加新的分析器或者对现有的字段做改动。 如果你那么做的话,结果就是那些已经被索引的数据就不正确, 搜索也不能正常工作。

对现有数据的这类改变最简单的办法就是重新索引:用新的设置创建新的索引并把文档从旧的索引复制到新的索引。

为了有效的重新索引所有在旧的索引中的文档,用 scroll 从旧的索引检索批量文档 , 然后用 bulk API 把文档推送到新的索引中。

同时并行运行多个重建索引任务,但是你显然不希望结果有重叠。正确的做法是按日期或者时间 这样的字段作为过滤条件把大的重建索引分成小的任务:

  1. GET /old_index/_search?scroll=1m
  2. {
  3. "query": {
  4. "range": {
  5. "date": {
  6. "gte": "2014-01-01",
  7. "lt": "2014-02-01"
  8. }
  9. }
  10. },
  11. "sort": ["_doc"],
  12. "size": 1000
  13. }
  14.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

如果旧的索引持续会有变化,你希望新的索引中也包括那些新加的文档。那就可以对新加的文档做重新索引, 但还是要用日期类字段过滤来匹配那些新加的文档。

通过创建新的索引,将数据重新迁移到新索引中,这种变相的更改索引的配置的方式的缺点是改变了原索引的名称(索引名称不允许重复,新索引就要使用新的索引名)。

注意

  • 禁用_all或者通配符,防止误操作

    对一些人来说,能够用单个命令来删除所有数据可能会导致可怕的后果。如果你想要避免意外的大量删除, 你可以在你的 elasticsearch.yml 做如下配置:action.destructive_requires_name: true

    这个设置使删除只限于特定名称指向的数据, 而不允许通过指定 _all 或通配符来删除指定索引库。你同样可以通过 Cluster State API 动态的更新这个设置。

我的微信公众号:

Elasticsearch入门教程(三):Elasticsearch索引&映射的更多相关文章

  1. ElasticSearch入门 第三篇:索引

    这是ElasticSearch 2.4 版本系列的第三篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  2. Elasticsearch入门教程(二):Elasticsearch核心概念

    原文:Elasticsearch入门教程(二):Elasticsearch核心概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:ht ...

  3. Elasticsearch入门教程(六):Elasticsearch查询(二)

    原文:Elasticsearch入门教程(六):Elasticsearch查询(二) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:h ...

  4. Elasticsearch入门教程(五):Elasticsearch查询(一)

    原文:Elasticsearch入门教程(五):Elasticsearch查询(一) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:h ...

  5. Elasticsearch入门教程(一):Elasticsearch及插件安装

    原文:Elasticsearch入门教程(一):Elasticsearch及插件安装 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:h ...

  6. Elasticsearch入门教程(四):Elasticsearch文档CURD

    原文:Elasticsearch入门教程(四):Elasticsearch文档CURD 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接: ...

  7. 无废话ExtJs 入门教程三[窗体:Window组件]

    无废话ExtJs 入门教程三[窗体:Window组件] extjs技术交流,欢迎加群(201926085) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3 ...

  8. PySide——Python图形化界面入门教程(三)

    PySide——Python图形化界面入门教程(三) ——使用内建新号和槽 ——Using Built-In Signals and Slots 上一个教程中,我们学习了如何创建和建立交互widget ...

  9. RabbitMQ入门教程(三):Hello World

    原文:RabbitMQ入门教程(三):Hello World 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog. ...

随机推荐

  1. ZOJ - 3780-Paint the Grid Again-(拓扑排序)

    Description Leo has a grid with N × N cells. He wants to paint each cell with a specific color (eith ...

  2. Mysql启动报错 The server quit without updating PID

    [root@db mysql]# service mysql restartMySQL server PID file could not be found![失败]Starting MySQL... ...

  3. 扫描工具-Nikto

    靶机 192.168.1.101 攻击机 192.168.1.102 尝试ping命令 第一个工具 作用 Httrack --->(把目标的网站复制过来) 这样可以减少与目标系统的交互 mkdi ...

  4. C++入门经典-例3.5-判断某一年是否是闰年之嵌套判断

    1:代码如下: // 3.5.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using ...

  5. legend3---4、lavarel中session使用注意

    legend3---4.lavarel中session使用注意 一.总结 一句话总结: session('key',$value)不是存值,是设置默认值,session(['key'=>$val ...

  6. sonarqube修改自己的图像avatar

    https://community.sonarsource.com/t/how-can-i-change-my-avatar/11457/2 Hi, User icons are provided b ...

  7. typescript 函数(定义、参数、重载)

    代码: // 本节内容 // 1.函数的定义 // 2.参数(可选参数/默认参数/剩余参数) // 3.方法的重载 // js // function add(x,y){ // return x+y ...

  8. SQLServer备份计划制定

    SQLServer备份计划制定 一.备份计划制定 管理-->维护计划-->维护计划向导: 可选择全库备份.差异备份.事务日志备份 为保障数据的完整性:可采用备份策略1.数据量小的场景,数据 ...

  9. golang网络通信超时设置

    网络通信中,为了防止长时间无响应的情况,经常会用到网络连接超时.读写超时的设置. 本文结合例子简介golang的连接超时和读写超时设置. 1.超时设置 1.1 连接超时 func DialTimeou ...

  10. Electron对JQuery的支持问题

    最近在了解Electron框架写应用,偶然发现在html中使用<script src="./jquery.js"></script>这种方式引入JQuery ...