公号:码农充电站pro

主页:https://codeshellme.github.io

DSL(Domain Specific Language)查询也叫做 Request Body 查询,它比 URI 查询更高阶,能支持更复杂的查询。

1,分页

默认情况下,查询按照算分排序,返回前 10 条记录。

ES 也支持分页,分页使用 from-size

  • from:从第几个文档开始返回,默认为 0。
  • size:返回的文档数,默认为 10。

示例:

POST /index_name/_search
{
"from":10,
"size":20,
"query":{
"match_all": {}
}
}

1.1,深度分页问题

ES 是一个分布式系统,数据保存在多个分片中,那么查询时就需要查询多个分片。

比如一个查询 from = 990; size = 10,那么 ES 需要在每个分片上都获取 1000 个文档:

然后通过 Coordinating 节点汇总结果,最后再通过排序获取前 1000 个文档。

这种方式,当页数很深的时候,就会占用很多内存,从而给 ES 集群带来很大的开销,这就是深度分页问题

因此,ES 为了避免此类问题带来的巨大开销,有个默认的限制 index.max_result_windowfrom + size 必须小于等于 10000,否则就会报错

比如:

POST index_name/_search
{
"from": 10000, # 报错
"size": 1,
"query": {
"match_all": {}
}
} POST index_name/_search
{
"from": 0, # 报错
"size": 10001,
"query": {
"match_all": {}
}
}

为了解决深度分页问题,ES 有两种解决方案:Search AfterScroll

1.2,Search After

Search After 通过实时获取下一页的文档信息来实现,使用方法:

  • 第一步搜索需要指定 sort,并且保证值是唯一的(通过sort by id 来保证)。
  • 随后的搜索,都使用上一次搜索的最后一个文档的 sort 值进行搜索。

Search After 的方式不支持指定页数,只能一页一页的往下翻。

Search After 的原理:

示例:

# 插入一些数据
DELETE users POST users/_doc
{"name":"user1","age":10} POST users/_doc
{"name":"user2","age":11} POST users/_doc
{"name":"user2","age":12} POST users/_doc
{"name":"user2","age":13} # 第一次搜索
POST users/_search
{
"size": 1, # size 值
"query": {
"match_all": {}
},
"sort": [
{"age": "desc"} ,
{"_id": "asc"} # sort by id
]
} # 此时返回的文档中有一个 sort 值
# "sort" : [13, "4dR-IHcB71-f4JZcrL2z"] # 之后的每一次搜索都需要用到上一次搜索结果的最后一个文档的 sort 值
POST users/_search
{
"size": 1,
"query": {
"match_all": {}
},
"search_after": [ # 上一次搜索结果的最后一个文档的 sort 值放在这里
13, "4dR-IHcB71-f4JZcrL2z"],
"sort": [
{"age": "desc"} ,
{"_id": "asc"}
]
}

1.3,Scroll

Scroll 通过创建一个快照来实现,方法:

  • 每次查询时,输入上一次的 Scroll Id

Scroll 方式的缺点是,当有新的数据写入时,新写入的数据无法被查到(第一次建立快照时有多少数据,就只能查到多少数据)。

示例:

# 写入测试数据
DELETE users
POST users/_doc
{"name":"user1","age":10} POST users/_doc
{"name":"user2","age":20} # 第一次查询前,先建立快照,快照存在时间为 5 分钟,一般不要太长
POST /users/_search?scroll=5m
{
"size": 1,
"query": {
"match_all" : {}
}
} # 返回的结果中会有一个 _scroll_id # 查询
POST /_search/scroll
{
"scroll" : "1m", # 快照的生存时间,这里是 1 分钟
"scroll_id" : "xxx==" # 上一次的 _scroll_id 值
} # 每次的查询结果都会返回一个 _scroll_id,供下一次查询使用
# 所有的数据被查完以后,再查询就得不到数据了

1.4,不同分页方式的使用场景

分页方式共 4 种:

  • 普通查询(不使用分页):需要实时获取顶部的部分文档。
  • From-Size(普通分页):适用于非深度分页。
  • Search After:需要深度分页时使用。
  • Scroll:需要全部文档,比如导出全部数据。

2,排序

ES 默认使用算分进行排序,我们可以使用 sort-processor(不需要再计算算分)来指定排序规则;可以对某个字段进行排序,最好只对数字型日期型字段排序。

示例:

POST /index_name/_search
{
"sort":[{"order_date":"desc"}], # 单字段排序
"query":{
"match_all": {}
}
} POST /index_name/_search
{
"query": {
"match_all": {}
},
"sort": [ # 多字段排序
{"order_date": {"order": "desc"}},
{"_doc":{"order": "asc"}},
{"_score":{ "order": "desc"}} # 如果不指定 _score,那么算分为 null
]
}

text 类型的数据进行排序会发生错误,可以通过打开 fielddata 参数(一般不建议这么做),来对 text 类型进行排序:

# 打开 text的 fielddata
PUT index_name/_mapping
{
"properties": {
"customer_full_name" : { # 字段名称
"type" : "text",
"fielddata": true, # 打开 fielddata
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}

3,字段过滤

可以使用 _source 设置需要返回哪些字段。示例:

POST /index_name/_search
{
"_source":["order_date", "xxxxx"],
"query":{
"match_all": {}
}
}

_source 中可以使用通配符,比如 ["name*", "abc*"]

4,脚本字段

可以使用脚本进行简单的表达式运算。

POST /index_name/_search
{
"script_fields": { # 固定写法
"new_field": { # 新的字段名称
"script": { # 固定写法
"lang": "painless", # 固定写法
"source": "doc['order_date'].value+'hello'" # 脚本语句
}
}
},
"query": {
"match_all": {}
}
}

5,查询与过滤

查询会有相关性算分;过滤不需要进行算分,可以利用缓存,性能更好。

参考这里

6,全文本查询

全文本(Full text)查询会对搜索字符串进行分词处理

全文本查询有以下 9 种:

  1. intervals 查询:可以对匹配项的顺序和接近度进行细粒度控制。
  2. match 查询:全文本查询中的标准查询,包括模糊匹配、短语和近似查询。
  3. match_bool_prefix 查询
  4. match_phrase 查询
  5. match_phrase_prefix 查询
  6. multi_match 查询
  7. common terms 查询
  8. query_string 查询
  9. simple_query_string 查询

6.1,Match 查询

Match 查询是全文搜索的标准查询,与下面的几种查询相比,更加强大,灵活性也更大,最常使用。

Match 查询会先对输入字符串进行分词,然后对每个词项进行底层查询,最后将结果合并。

例如对字符串 "Matrix reloaded" 进行查询,会查到包含 "Matrix" 或者 "reloaded" 的所有结果。

示例:

POST index_name/_search
{
"query": {
"match": {
"title": "last christmas" # 表示包含 last 或 christmas
}
}
} POST index_name/_search
{
"query": {
"match": {
"title": { # 表示包含 last 且 包含 christmas,不一定挨着
"query": "last christmas",
"operator": "and"
}
}
}
}

6.2,Match Phrase 查询

使用 match_phrase 关键字。示例:

POST index_name/_search
{
"query": {
"match_phrase": {
"title":{
"query": "one love" # "one love" 相当于一个单词
}
}
}
} POST index_name/_search
{
"query": {
"match_phrase": {
"title":{
"query": "one love",
"slop": 1 # "one" 和 "love" 之间可以有 1 个字符
}
}
}
}

6.3,Query String 查询

使用 query_string 关键字。示例:

POST index_name/_search
{
"query": {
"query_string": {
"default_field": "name", # 默认查询字段,相当于 URI 查询中的 df
"query": "Ruan AND Yiming" # 可以使用逻辑运算符
}
}
} # 多 fields 与 分组
POST index_name/_search
{
"query": {
"query_string": {
"fields":["name","about"], # 多个 fields
"query": "(Ruan AND Yiming) OR (Java AND Elasticsearch)" # 支持分组
}
}
} POST index_name/_search
{
"query":{
"query_string":{
"fields":["title","year"],
"query": "2012"
}
}
}

6.4,Simple Query String 查询

使用 simple_query_string 关键字。

特点:

  • query 字段中不支持 AND OR NOT,会当成普通字符串。

    • AND+ 替代
    • OR| 替代
    • NOT- 替代
  • Term 之间默认的关系是 OR,可以指定 default_operator 来修改。

示例:

# Simple Query 默认的 operator 是 OR
POST index_name/_search
{
"query": {
"simple_query_string": {
"query": "Ruan AND Yiming", # 这里的 AND 会当成普通的字符串
"fields": ["name"]
}
}
} POST index_name/_search
{
"query": {
"simple_query_string": {
"query": "Ruan Yiming",
"fields": ["name"],
"default_operator": "AND"
}
}
} GET index_name/_search
{
"query":{
"simple_query_string":{
"query":"Beautiful +mind",
"fields":["title"]
}
}
}

6.5,Multi-match 查询

一个字符串在多个字段中查询的情况,如何匹配最终的结果。(还有一个 dis-max 查询也是针对这种情况的)

一个字符串在多个字段中查询的情况,Multi-match 有 6 种处理方式,如下:

  • best_fields:最终得分为分数最高的那个字段,默认的处理方式。
  • most_fields:算分相加。不支持 AND 操作。
  • cross_fields:跨字段搜索,将一个查询字符串在多个字段(就像一个字段)上搜索。
  • phrase
  • phrase_prefix
  • bool_prefix

示例:

POST index_name/_search
{
"query": {
"multi_match" : { # multi_match 查询
"query": "brown fox", # 查询字符串
"type": "best_fields", # 处理方式
"fields": [ "subject", "message" ], # 在多个字段中查询,fields 是一个数组
"tie_breaker": 0.3
}
}
}

7,Term 查询

Term 查询全文本查询不同的是,Term 查询不会对查询字符串进行分词处理,Term 查询会在字段匹配精确值

Term 查询输入字符串作为一个整体,在倒排索引中查找匹配的词项,并且会计算相关性评分

Term 查询包括以下 11 种:

  1. exists 查询
  2. fuzzy 查询
  3. ids 查询
  4. prefix 查询
  5. range 查询
  6. regexp 查询
  7. term 查询:如果某个文档的指定字段包含某个确切值,则返回该文档。
  8. terms 查询
  9. terms_set 查询
  10. type 查询
  11. wildcard 查询

7.0,结构化数据与查询

结构化查询是对结构化数据的查询,可以使用 Term 语句进行查询。

结构化数据有着固定的格式,包括:

  • 日期:日期比较,日期范围运算等。
  • 布尔值:逻辑运算。
  • 数字:数字大小比较,范围比较等。
  • 某些文本数据:比如标签数据,关键词等。

结构化查询是对结构化数据的逻辑运算,运算结果只有“是”和“否”。

7.1,term 查询

如果某个文档的指定字段包含某个确切值,则返回该文档。

1,示例 1 精确匹配

下面举一个 term 查询的例子,首先插入一个文档:

POST /products/_bulk
{ "index": { "_id": 1 }}
{ "productID" : "XHDK-A-1293-#fJ3","desc":"iPhone" }

该文档插入时,会使用默认的分词器进行分词处理。

使用 term 查询:

POST /products/_search
{
"query": {
"term": {
"desc": {
# "value": "iPhone" # 会对 iPhone 精确匹配查询。
# 文档插入时,iPhone 变成了 iphone
# 所以查 iPhone 查不到任何内容
"value":"iphone" # 查 iphone 能查到
}
}
}
}

keyword 子字段

ES 默认会对 text 类型的数据建立一个 keyword 子字段,用于精确匹配,这称为 ES 的多字段属性

keyword 子字段将原始数据原封不动的存储了下来。

可以通过 mapping 查看,如下所示:

"desc" : {          # 字段名称
"type" : "text", # text 数据类型
"fields" : {
"keyword" : { # keyword 子字段
"type" : "keyword", # keyword 子类型
"ignore_above" : 256
}
}
}

下面使用 keyword 子字段进行查询:

POST /products/_search
{
"query": {
"term": {
"desc.keyword": { # 在 desc 字段的 keyword 子字段中查询
"value": "iPhone" # 能查到
//"value":"iphone" # 查不到
}
}
}
}
2,示例 2 查询布尔值

term 查询有算分:

POST index_name/_search
{
"query": { # 固定写法
"term": { # term 查询,固定写法
"avaliable": true # 查询 avaliable 字段的值为 true 的文档
}
}
}

如果不需要算分,可以使用 constant_score 查询,示例:

POST index_name/_search
{
"query": {
"constant_score": { # constant_score 查询,固定写法
"filter": { # 固定写法
"term": { # constant_score 包装一个 term 查询,就没有了算分
"avaliable": true
}
}
}
}
}

7.2,range 查询

range 查询中有几个常用的比较运算:

运算符 含义
gt 大于
gte 大于等于
lt 小于
lte 小于等于
1,数字类型 range 查询

示例:

POST index_name/_search
{
"query": { # 固定写法
"range": { # range 查询
"age": { # 字段名称
"gte": 10, # 10 <= age <= 20
"lte": 20
}
}
}
}
2,日期类型 range 查询

对于日期类型有几个常用的符号:

符号 含义
y
M
w
d
H / h 小时
m 分钟
s
now 现在

示例:

POST index_name/_search
{
"query" : { # 固定写法
"range" : { # range 查询
"date" : { # 字段名称
"gte" : "now-10y" # 10年之前
}
}
}
}

7.3,exists 查询

exists 语句可以判断文档是否存在某个字段

搜索存在某个字段的文档,示例:

POST index_name/_search
{
"query" : {
"exists": { # 存在 date 字段的文档
"field": "date"
}
}
}

搜索不存在某个字段的文档,需要使用布尔查询

示例:

POST index_name/_search
{
"query": {
"bool": { # 布尔查询
"must_not": { # 不存在
"exists": { # 不存在 date 字段的文档
"field": "date"
}
}
}
}
}

7.4,terms 查询

terms 语句用于处理多值查询,相当于一个多值版的 term 语句,可以一次查询多个值。

示例:

POST index_name/_search
{
"query": {
"terms": { # terms 查询
"productID.keyword": [ # 字段名称
"QQPX-R-3956-#aD8", # 多个值
"JODL-X-1937-#pV7"
]
}
}
}

8,复合查询

复合查询(Compound)能够包装其他复合查询叶查询,以组合其结果和分数,更改其行为或者将查询转成过滤

复合查询有以下 5 种:

8.1,bool 查询

bool 查询是一个或多个子查询的组合,共包含以下 4 种子句:

  • must:必须匹配,属于查询,贡献算分。
  • filter:必须匹配,属于过滤器,不贡献算分。
  • should:选择性匹配,只要有一个条件匹配即可,属于查询,贡献算分。
  • must_not:必须不匹配,属于过滤器,不贡献算分。

bool 查询的多个子句之间没有顺序之分,并且可以嵌套

示例:

POST index_name/_search
{
"query": {
"bool" : {
"must" : {
"term" : { "user.id" : "kimchy" }
},
"filter": {
"term" : { "tags" : "production" }
},
"must_not" : {
"range" : {
"age" : { "gte" : 10, "lte" : 20 }
}
},
"should" : [ # 是一个数组
{ "term" : { "tags" : "env1" } },
{ "term" : { "tags" : "deployed" } }
],
"minimum_should_match" : 1,
"boost" : 1.0
}
}
}

8.2,boosting 查询

boosting 查询会给不同的查询条件分配不同的级别(positive / negative),不同的级别对算分有着不同的印象,从而影响最终的算分。

positive 级别会对算分有正面影响negative 级别会对算分有负面影响

我们可以使用 boosting 查询给某些文档降级(降低算分),而不是将其从搜索结果中排除

示例:

GET index_name/_search
{
"query": {
"boosting": { # boosting 查询
"positive": { # positive 级别
"term": { # 匹配 apple 的会对算分有正面影响
"text": "apple"
}
},
"negative": { # negative 级别
"term": { # 匹配这个的会对算分有负面影响
"text": "pie tart fruit crumble tree"
}
},
"negative_boost": 0.5 # 降级的力度
}
}
}

8.3,constant_score 查询

constant_score 查询可以将查询转成一个过滤,可以避免算分(降低开销),并有效利用缓存(提高性能)。

示例:

POST /index_name/_search
{
"query": {
"constant_score": { # constant_score 查询
"filter": { # 过滤器,固定写法
"term": { # 包装了一个 term 查询,将 term 查询转成了过滤
"productID.keyword": "XHDK-A-1293-#fJ3"
}
}
}
}
}

8.4,dis_max 查询

一个字符串在多个字段中查询的情况,如何匹配最终的结果。(还有一个 Multi-match 查询也是针对这种情况的)

示例:

POST index_name/_search
{
"query": {
"bool": {
"should": [ # should 语句会综合所有的字段的分数,最终给出一个综合分数
{ "match": { "title": "Brown fox" }},
{ "match": { "body": "Brown fox" }}
]
}
}
} POST index_name/_search
{
"query": {
"dis_max": { # dis_max 语句不会综合所有字段的分数,而把每个字段单独来看
"queries": [ # 最终结果是所有的字段中分数最高的
{ "match": { "title": "Quick pets" }},
{ "match": { "body": "Quick pets" }}
]
}
}
}

8.5,function_score 查询

function_score 查询可以在查询结束后,对每一个匹配的文档进行重新算分,然后再根据新的算分进行排序。

它提供了以下 5 种算分函数:

  • script_score:自定义脚本。
  • weight:为文档设置一个权重。
  • random_score:随机算分排序。
  • field_value_factor:使用该数值来修改算分。
  • decay functions: gauss, linear, exp:以某个字段为标准,距离某个值越近,得分越高。
1,field_value_factor 示例

首先插入测试数据:

DELETE blogs
PUT /blogs/_doc/1
{
"title": "About popularity",
"content": "In this post we will talk about...",
"votes": 0
} PUT /blogs/_doc/2
{
"title": "About popularity",
"content": "In this post we will talk about...",
"votes": 100
} PUT /blogs/_doc/3
{
"title": "About popularity",
"content": "In this post we will talk about...",
"votes": 1000000
}

查询示例1:

新的算分 = 老的算分 * 投票数

POST /blogs/_search
{
"query": {
"function_score": {
"query": {
"multi_match": { # 该查询会有一个算分
"query": "popularity",
"fields": [ "title", "content" ]
}
},
"field_value_factor": { # 最终的算分要乘以 votes 字段的值
"field": "votes"
}
}
}
}

上面这种算法当出现这两种情况的时候,会出现问题:

  • 投票数为 0
  • 投票数特别大

查询示例2,引入平滑函数

新的算分 = 老的算分 * 平滑函数(投票数)

POST /blogs/_search
{
"query": {
"function_score": {
"query": {
"multi_match": {
"query": "popularity",
"fields": [ "title", "content" ]
}
},
"field_value_factor": {
"field": "votes",
"modifier": "log1p" # 在原来的基础上加了一个平滑函数
} # 新的算分 = 老的算分 * log(1 + 投票数)
}
}
}

平滑函数有下面这些:

查询示例3,引入 factor

新的算分 = 老的算分 * 平滑函数(factor * 投票数)

POST /blogs/_search
{
"query": {
"function_score": {
"query": {
"multi_match": {
"query": "popularity",
"fields": [ "title", "content" ]
}
},
"field_value_factor": {
"field": "votes",
"modifier": "log1p" ,
"factor": 0.1
}
}
}
}

引入 factor 之后的算分曲线:

2,Boost Mode 和 Max Boost 参数

Boost Mode:

  • Multiply:算分与函数值的乘积。
  • Sum:算分与函数值的和。
  • Min / Max:算分与函数值的最小/最大值。
  • Replace:使用函数值替代算分。

Max Boost 可以将算分控制在一个最大值。

示例:

POST /blogs/_search
{
"query": {
"function_score": {
"query": {
"multi_match": {
"query": "popularity",
"fields": [ "title", "content" ]
}
},
"field_value_factor": {
"field": "votes",
"modifier": "log1p" ,
"factor": 0.1
},
"boost_mode": "sum",
"max_boost": 3
}
}
}
3,random_score 示例

示例:

POST /blogs/_search
{
"query": {
"function_score": {
"random_score": { # 将原来的查询结果随机排序
"seed": 911119 # 随机种子
}
}
}
}

(本节完。)


推荐阅读:

ElasticSearch 查询

ElasticSearch URI 查询

ElasticSearch 文档及操作

ElasticSearch 分词器

ElasticSearch 搜索引擎概念简介


欢迎关注作者公众号,获取更多技术干货。

ElasticSearch DSL 查询的更多相关文章

  1. elasticsearch DSL查询

    总结一个DSL的用法吧,语法网上查去,只记录一点心得,也是研究了半天,太麻烦了 先附上python代码 #!/usr/bin/env python # _*_ coding:utf-8 _*_ fro ...

  2. Elasticsearch Query DSL查询入门

    本篇为学习DSL时做的笔记,适合ES新手,大佬请略过~ Query DSL又叫查询表达式,是一种非常灵活又富有表现力的查询语言,采用JSON接口的方式实现丰富的查询,并使你的查询语句更灵活.更精确.更 ...

  3. ES 20 - 查询Elasticsearch中的数据 (基于DSL查询, 包括查询校验match + bool + term)

    目录 1 什么是DSL 2 DSL校验 - 定位不合法的查询语句 3 match query的使用 3.1 简单功能示例 3.1.1 查询所有文档 3.1.2 查询满足一定条件的文档 3.1.3 分页 ...

  4. 【转】elasticsearch的查询器query与过滤器filter的区别

    很多刚学elasticsearch的人对于查询方面很是苦恼,说实话es的查询语法真心不简单-  当然你如果入门之后,会发现elasticsearch的rest api设计是多么有意思. 说正题,ela ...

  5. ELK学习笔记(五)简单搜索和DSL查询

    检索文档 现在我们有一些数据存储在Elasticsearch中,我们可以开始处理这个应用程序的业务需求. 这在Elasticsearch中很容易.我们只需执行HTTP GET请求并指定文档的地址--索 ...

  6. ElasticSearch 常用查询语句

    为了演示不同类型的 ElasticSearch 的查询,我们将使用书文档信息的集合(有以下字段:title(标题), authors(作者), summary(摘要), publish_date(发布 ...

  7. 基于百度地图SDK和Elasticsearch GEO查询的地理围栏分析系统(1)

    本文描述了一个系统,功能是评价和抽象地理围栏(Geo-fencing),以及监控和分析核心地理围栏中业务的表现. 技术栈:Spring-JQuery-百度地图WEB SDK 存储:Hive-Elast ...

  8. Elasticsearch Kibana查询语法

    Elasticsearch Kibana查询语法 2018年06月03日 23:52:30 wangpei1949 阅读数:3992   Elasticsearch Kibana Discover的搜 ...

  9. ElasticSearch—分页查询

    ElasticSearch查询—分页查询详解 Elasticsearch中数据都存储在分片中,当执行搜索时每个分片独立搜索后,数据再经过整合返回.那么,如何实现分页查询呢? 按照一般的查询流程来说,如 ...

  10. Elasticsearch 邻近查询示例

    Elasticsearch 邻近查询示例(全切分分词) JAVA API方式: SpanNearQueryBuilder span = QueryBuilders.spanNearQuery(); s ...

随机推荐

  1. sql 批量更新某个字段的值

    UPDATE Tabel1 t1 set t1.col1= ( SELECT col2 from Tabel2 t2 WHERE t1.col1=t2.col2) where exists ( SEL ...

  2. node 日志管理log4js

    node 日志管理log4js 一.默认的控制台输出 我们使用express框架时,开发模式用node或者supervisor启动nodejs应用时,控制台都是显示如下的日志. GET /css/bo ...

  3. Guava 8-区间

    范例 List scores; Iterable belowMedian =Iterables.filter(scores,Range.lessThan(median)); ... Range val ...

  4. 设置ORACLE数据库游标大小

    先用超级管理员(sys)登陆服务器: sqlplus "sys/***@orcl as sysdba" 连接到:Oracle 查看ORACLE最大游标数: SQL> show ...

  5. iOS 动画基础

    原文:http://www.cnblogs.com/lujianwenance/p/5733846.html   今天说一下有关动画的基础,希望能帮助到一些刚接触iOS动画或者刚开始学习iOS的同学, ...

  6. BZOJ 1261: [SCOI2006]zh_tree( 区间dp )

    dp(l, r)表示[l, r]这段作为一棵树的最小访问代价. 对于dp(l, r), 我们枚举它的根x, 则dp(l, r) = min(dp(l, x-1)+dp(x+1, r)+C*fx) + ...

  7. mybatis 的简单使用

    须要用到的包:(这里仅仅是当中一个版本号.其它的百度) mysql-connector-java-5.1.6-bin mybatis-3.2.2 先看项目文件夹: 配置文件mybatisconfig. ...

  8. java 读取URL中的资源

    Example13_1.java import java.net.*; import java.io.*; import java.util.*; public class Example13_1 { ...

  9. Static语句块和初始语句块的使用---2015年10月恒生电子笔试试卷

    package lhm.test; /** * @author lenovo * */public class Person { private int id; private static int ...

  10. 原生JS实现简易轮播图

    原生JS实现简易轮播图(渐变?) 最近做网页总是会用到轮播图,我就把之前写的轮播图单独拿出来吧,如果有...如果真的有人也需要也可以复制去用用啊..哈~.. window.onload = funct ...