(六)ElasticSearch 6.1.1聚合查询

1 普通类型

1.1 基本操作

1.1.1 导入实战数据

数据字段如下:

字段类型作用
pricelong汽车售价
colortext汽车颜色
maketext汽车品牌
solddate销售日期
# 创建索引
PUT /cars
{"mappings" : {"transactions" : {"properties" : {"color" : {"type" : "keyword"},"make" : {"type" : "keyword"},"price" : {"type" : "long"},"sold" : {"type" : "date"}}}}
}# 导入数据
POST /cars/transactions/_bulk
{ "index": {}}
{ "price" : 10000, "color" : "red", "make" : "honda", "sold" : "2014-10-28" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 30000, "color" : "green", "make" : "ford", "sold" : "2014-05-18" }
{ "index": {}}
{ "price" : 15000, "color" : "blue", "make" : "toyota", "sold" : "2014-07-02" }
{ "index": {}}
{ "price" : 12000, "color" : "green", "make" : "toyota", "sold" : "2014-08-19" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 80000, "color" : "red", "make" : "bmw", "sold" : "2014-01-01" }
{ "index": {}}
{ "price" : 25000, "color" : "blue", "make" : "ford", "sold" : "2014-02-12" }

1.1.2 最简单的聚合:terms桶

# 第一个聚合命令是terms桶,相当于SQL中的group by,将所有记录按照颜色聚合
GET /cars/transactions/_search
{"size":0,"aggs":{"popular_colors":{"terms": {"field": "color"}} }
}

运行结果

1.1.3 添加度量指标

  • 上面的示例返回的是每个桶中的文档数量,接下es支持丰富的指标,例如平均值(Avg)、最大值(Max)、最小值(Min)、累加和(Sum)等,接下来试试累加和的用法;
  • 下面请求的作用是统计每种颜色汽车的销售总额:
GET /cars/transactions/_search
{"size":0,"aggs":{"colors":{"terms": {"field": "color"},"aggs":{"sales":{"sum":{"field":"price"}}}} }
}# 解释
GET /cars/transactions/_search
{"size":0,"aggs":{         ------和前面一样,指定聚合操作"colors":{      ------别名"terms": {    ------桶类型是按指定字段聚合"field": "color" ------按照color字段聚合},"aggs":{      ------新增的aggs对象,用于处理聚合在每个桶内的文档"sales":{   ------别名"sum":{   ------度量指标是指定字段求和"field":"price" ---求和的字段是price}}}} }
}"aggregations" : {               ------聚合结果"colors" : {"doc_count_error_upper_bound" : 0,"sum_other_doc_count" : 0,"buckets" : [               ------这个json数组的每个对象代表一个桶{"key" : "red",        ------该桶将所有color等于red的文档聚合进来"doc_count" : 4,      ------有4个color等于red的文档"sales" : {           ------这里面是sum计算后的结果  "value" : 130000.0  ------所有color等于red的汽车销售总额}},{"key" : "blue","doc_count" : 2,"sales" : {"value" : 40000.0  ------所有color等于blue的汽车销售总额}},

1.2 区间聚合

1.2.1条形图(histogram桶)

以汽车销售记录为例做一次聚合查询,为售价创建histogram桶,以20000作为间隔,每个桶负责的区间如上图所示,相关的销售记录就会被放入对应的桶中,请求参数和说明如下:

# 可执行查询
GET /cars/transactions/_search
{"size":0,                  "aggs":{                   "price":{                 "histogram": {          "field": "price",     "interval": 20000     }} }
}
# 解释
GET /cars/transactions/_search
{"size":0,                  ---令返回值的hits对象为空"aggs":{                   ---聚合命令"price":{                 ---聚合字段名称"histogram": {          ---桶类型"field": "price",     ---指定price字段的值作为判断条件"interval": 20000     ---每个桶负责的区间大小为20000}} }
}# 返回结果"aggregations" : {             ---聚合结果"price" : {                  ---请求参数中指定的名称"buckets" : [              ---price桶的数据在此数组中{"key" : 0.0,           ---第一个桶,区间[0-19999],0.0是起始值"doc_count" : 3        ---这个区间有三个文档(price值分别是10000、12000、15000)},{"key" : 20000.0,       ---第二个桶,区间[20000-39999],20000.0是起始值"doc_count" : 4        ---这个区间有四个文档},{"key" : 40000.0,       ---第三个桶,区间[40000-59999],40000.0是起始值"doc_count" : 0        ---这个区间没有文档},......

1.2.2 控制空桶是否返回

在上面的返回值中,第三个桶中没有文档,在有的业务场景中,我们不需要没有数据的桶,此时可以用min_doc_count参数来控制,如果min_doc_count等于2,表示桶中最少有两条记录才会出现在返回内容中,如下所示,min_doc_count如果等于1,那么空桶就不会被es返回了:

GET /cars/transactions/_search
{"size":0,"aggs":{"price":{"histogram": {"field": "price","interval": 20000,"min_doc_count": 1}} }
}

1.2.3 histogram桶加metrics

上面的例子返回结果只有每个桶内的文档数,也可以加入metrics对桶中的数据进行处理,例如计算每个区间内的最高价、最低价、平均售价,可以加入max、min、avg参数,如下:

# 可执行查询
GET /cars/transactions/_search
{"size":0,                  "aggs":{                   "price":{                 "histogram": {          "field": "price",     "interval": 20000,    "min_doc_count": 1},"aggs": {               "max_price": {       "max":{            "field": "price" }},"min_price": {       "min":{            "field": "price" }},"avg_price": {       "avg":{            "field": "price" }}}} }
}# 解释
GET /cars/transactions/_search
{"size":0,                  ---令返回值的hits对象为空"aggs":{                   ---聚合命令"price":{                 ---聚合字段名称"histogram": {          ---桶类型"field": "price",     ---指定price字段的值作为判断条件"interval": 20000     ---每个桶负责的区间大小为20000},"aggs": {               ---表示对桶内数据做metrics"max_price": {       ---指定metrics处理结果的字段名"max":{            ---metrics类型为max"field": "price" ---指定取price字段的值做最大值比较}},"min_price": {       ---指定metrics处理结果的字段名"min":{            ---metrics类型为min"field": "price" ---指定取price字段的值做最小值比较}},"avg_price": {       ---指定metrics处理结果的字段名"avg":{            ---metrics类型为avg"field": "price" ---指定取price字段的值计算平均值}}}} }
}# 返回结果"aggregations" : {             ---聚合结果"price" : {                  ---请求参数中指定的名称"buckets" : [              ---price桶的数据在此数组中{"key" : 0.0,           ---第一个区间[0-19999],0.0是起始值"doc_count" : 3,       ---这个区间有三条记录(price值分别是10000、12000、15000)"max_price" : {        ---指定的metrics结果名称"value" : 15000.0    ---桶中有三个文档,price字段的最大值是15000},"min_price" : {"value" : 10000.0    ---桶中有三个文档,price字段的最小值是10000},"avg_price" : {"value" : 12333.333333333334    ---桶中有三个文档,price字段的平均值是12333.333333333334}},......

1.2.4 时间区间的桶(date_histogram)

  • histogram桶可以实现按照时间分段么?如果用毫秒数来处理,似乎是可以的,但是对年月日的处理就力不从心了,常见的时间区间处理,用date_histogram桶即可满足要求;
  • 下面就是date_histogram桶的用法:每月销售多少台汽车:
GET /cars/transactions/_search
{
# 可执行查询
GET /cars/transactions/_search
{"size": 0,                    "aggs": {                     "sales": {                  "date_histogram": {       "field": "sold",        "interval": "month",    "format": "yyyy-MM-dd"  },"aggs": {                 "max_price": {          "max":{               "field": "price"    }},"min_price": {          "min":{               "field": "price"    }}}}}
}# 解释"size": 0,                    ---令返回值的hits对象为空"aggs": {                     ---聚合命令"sales": {                  ---聚合字段名称"date_histogram": {       ---桶类型"field": "sold",        ---用sold字段的值作进行时间区间判断"interval": "month",    ---间隔单位是月"format": "yyyy-MM-dd"  ---返回的数据中,时间字段格式},"aggs": {                 ---表示对桶内数据做metrics"max_price": {          ---指定metrics处理结果的字段名"max":{               ---metrics类型为max"field": "price"    ---指定取price字段的值做最大值比较}},"min_price": {          ---指定metrics处理结果的字段名"min":{               ---metrics类型为min"field": "price"    ---指定取price字段的值做最小值比较}}}}}
}# es返回
"aggregations" : {                           ---聚合结果"sales" : {                              ---请求参数中指定的名称"buckets" : [                          ---sales桶的数据在此数组中{"key_as_string" : "2014-01-01",    ---请求的format参数指定了key的格式"key" : 1388534400000,             ---真正的时间字段"doc_count" : 1,                   ---2014年1月份的文档数量"max_price" : {                    ---2014年1月的文档做了metrics类型为max的处理后,结果在此"value" : 80000.0                ---2014年1月的文档中,price字段的最大值},"min_price" : {                    ---2014年1月的文档做了metrics类型为min的处理后,结果在此"value" : 80000.0                ---2014年1月的文档中,price字段的最大值}},{"key_as_string" : "2014-02-01","key" : 1391212800000,"doc_count" : 1,"max_price" : {"value" : 25000.0},"min_price" : {"value" : 25000.0}},......

1.2.5 连续多次聚合

连续分桶,第二次分桶一定是在第一次分桶的基础上,对每一个桶再进行二次分桶,这一点可以在{}范围上看出,global关键字可以突破这个限制,但是两次分桶的结果仍然遵循{}的层次,这一点可以在全局桶体会到。

  • 来做一个略为复杂的聚合操作:按季度展示每个汽车品牌的销售总额;
  • 操作的第一步是按照时间区间做聚合,然后在每个桶中,将文档按照品牌做第二次聚合,第二次聚合的结果也可以理解为多个桶,每个桶中的文档,是某个平台在某个季度的销售总额;
# 可执行
GET /cars/transactions/_search
{"size": 0,                      "aggs": {                       "sales": {                    "date_histogram": {         "field": "sold",          "interval": "1q",         "format": "yyyy-MM-dd",   "min_doc_count": 1        },"aggs": {                   "per_make_sum": {         "terms": {              "field": "make"       },"aggs": {               "sum_price": {        "sum": {            "field": "price"  }}}}}}
}
}# 解释
GET /cars/transactions/_search
{"size": 0,                      ---令返回值的hits对象为空"aggs": {                       ---聚合命令"sales": {                    ---聚合字段名称"date_histogram": {         ---桶类型为时间区间"field": "sold",          ---指定sold字段的值作为判断条件"interval": "1q",         ---区间间隔为1季度"format": "yyyy-MM-dd",   ---返回的桶的key,被格式化时的格式"min_doc_count": 1        ---空桶不返回},"aggs": {                   ---第二层桶"per_make_sum": {         ---聚合字段名称"terms": {              ---桶类型为terms"field": "make"       ---按照make字段聚合},"aggs": {               ---第二层桶的metrics"sum_price": {        ---聚合字段名称"sum": {            ---metrics处理,累加"field": "price"  ---取price字段的值累加}}}}}}}
}# es返回
"aggregations" : {"sales" : {"buckets" : [                             ---聚合结果{"key_as_string" : "2014-01-01",       ---当前桶的key的格式化后的值"key" : 1388534400000,                ---当前桶的key原值"doc_count" : 2,                      ---当前桶中文档数"per_make_sum" : {                    ---第二层桶的名称"doc_count_error_upper_bound" : 0,"sum_other_doc_count" : 0,"buckets" : [                       ---第二层聚合结果{"key" : "bmw",                  ---聚合字段的值,这里是汽车品牌"doc_count" : 1,                ---桶内的文档数量"sum_price" : {                 ---metrics处理结果名称"value" : 80000.0             ---metrics处理结果,这里是销售额累加值}},{"key" : "ford",                 ---聚合字段的值,这里是汽车品牌"doc_count" : 1,                ---桶内的文档数量"sum_price" : {                 ---metrics处理结果名称"value" : 25000.0             ---metrics处理结果,这里是销售额累加值

1.3 范围限定

1.3.1 最简单的查询范围

福特汽车一共分为几种颜色?这就是最简单的范围限定聚合(限定了汽车品牌),查询DSL如下:

# 可执行
GET /cars/transactions/_search
{"size":0,"query": {                "term": {               "make": "ford"        }}, "aggs":{                  "popular_colors":{       "terms": {             "field": "color"     }} }
}# 解释
GET /cars/transactions/_search
{"size":0,"query": {                ---范围限定的查询"term": {               ---查询类型是精确匹配"make": "ford"        ---查询条件是品牌为福特}}, "aggs":{                  ---聚合"popular_colors":{       ---聚合字段名"terms": {             ---桶类型"field": "color"     ---匹配字段是color}} }
}# es返回"aggregations" : {                       ---聚合结果"popular_colors" : {                   ---聚合字段"doc_count_error_upper_bound" : 0,"sum_other_doc_count" : 0,"buckets" : [                        ---这个数组的元素是所有的桶{"key" : "blue",                  ---color为blue的文档"doc_count" : 1                  ---文档数为1},{"key" : "green",                 ---color为blue的文档"doc_count" : 1                  ---文档数为1}]}}
}

1.3.2 全局桶

如果想对比福特汽车的销售额和所有汽车的销售额,可以通过全局桶对所有文档做聚合,关键字是global,全局桶的聚合不受范围限定的影响:

# 可执行
GET /cars/transactions/_search
{"size": 0,"query": {			    "term": {               "make": "ford"        }},"aggs": {                  "ford_sales": {          "sum": {               "field": "price"     }},"all": {                 "global": {},          "aggs": {              "all_sales": {       "sum": {           "field": "price" }}}}}
}# 解释
GET /cars/transactions/_search
{"size": 0,"query": {			     ---范围限定的查询"term": {                ---查询类型是精确匹配"make": "ford"         ---查询条件是品牌为福特}},"aggs": {                  ---聚合"ford_sales": {          ---聚合字段名"sum": {               ---直接对范围内的所有文档执行metrics,类型是累加"field": "price"     ---选择price字段的值进行累加}},"all": {                 ---聚合字段名"global": {},          ---全局桶关键字,表示忽略前面term查询的范围限定"aggs": {              ---聚合"all_sales": {       ---聚合字段名"sum": {           ---直接对范围内的所有文档执行metrics,类型是累加"field": "price" ---选择price字段的值进行累加}}}}}
}
# es返回
......"aggregations" : {         ---聚合结果"all" : {                ---全局桶的聚合结果(term查询无效)"doc_count" : 8,       ---文档总数"all_sales" : {        ---聚合字段名"value" : 212000.0   ---总销售额}},"ford_sales" : {         ---聚合字段名(term查询限定了范围,只有福特汽车的销售记录)"value" : 55000.0      ---福特汽车销售额}}
}

1.3.3 使用filter提高查询性能

虽然query和filter限定范围的结果是一样的,但是filter会忽略评分,并且有可能缓存结果数据,这些都是性能上的优势。
前面的范围限定用到了query,其实适用于查询的过滤器也能应用在聚合操作中,下面是过滤+聚合的查询,和前面一样,也是统计总销售和和福特汽车的销售额:

# 可执行
GET /cars/transactions/_search
{"size": 0,"query": {"bool": {                 "filter": {             "term": {             "make": "ford"      }}}},"aggs": {                   "ford_sales": {           "sum": {                "field": "price"      }},"all": {                  "global": {},           "aggs": {               "all_sales": {        "sum": {            "field": "price"  }}}}}
}# 解释
GET /cars/transactions/_search
{"size": 0,"query": {"bool": {                 ---布尔查询,里面可以将query和filter组合使用"filter": {             ---本例只用到了filter"term": {             ---精确匹配"make": "ford"      ---匹配福特品牌 }}}},"aggs": {                   ---聚合结果"ford_sales": {           ---聚合字段名"sum": {                ---metrics操作,累加"field": "price"      ---累加字段是price}},"all": {                  ---聚合字段名                  "global": {},           ---全局桶关键字,表示忽略范围限定"aggs": {               ---聚合"all_sales": {        ---聚合字段名"sum": {            ---metrics操作,累加"field": "price"  ---累加字段是price}}}}}
}

1.3.4 桶内filter

学习桶内filter之前,先看看官方的布尔查询DSL,如下所示,查询JSON对象的内部可以加入filter,对查询结果做过滤:

GET /_search
{"query": { "bool": { "must": [                                     ---布尔查询{ "match": { "title":   "Search"        }}, { "match": { "content": "Elasticsearch" }}  ],"filter": [                                   ---对查询结果做过滤{ "term":  { "status": "published" }}, { "range": { "publish_date": { "gte": "2015-01-01" }}} ]}}
}
  • 桶内filter和布尔查询中的filter类似,对进入桶中的数据可以加入filter,这样桶内的数据就是此filter过滤后的数据了;
  • 举个例子,统计蓝色的福特汽车销售额,首先限定品牌范围,这个可以直接用之前的限定方式,然后在桶内加入一个filter,只保留颜色为蓝色的文档:
GET /cars/transactions/_search
{"size": 0,"query": {"bool": {                 ---布尔查询,里面可以将query和filter组合使用"filter": {             ---本例只用到了filter"term": {             ---精确匹配"make": "ford"      ---匹配福特品牌 }}}},"aggs": {"sales": {"filter": {             ---桶内filter"term": {             ---精确匹配"color": "blue"     ---匹配蓝色}},"aggs": {"blue_sales": {"sum": {            ---metrics操作,累加"field": "price"}}}}}
}# es返回"hits" : {"total" : 2,"max_score" : 0.0,"hits" : [ ]},"aggregations" : {"sales" : {"doc_count" : 1,"green_sales" : {"value" : 25000.0}}}
}

1.4 结果排序

1.4.1 默认排序

之前文章中的聚合查询,我们都没有做排序设置,此时es会用每个桶的doc_count字段做降序,下图是个terms桶聚合的示例,可见返回了三个bucket对象,是按照doc_count字段降序排列的:

1.4.2 内置排序

除了自定义排序,es自身也内置了两种排序参数,可以直接拿来使用:

# _count:这个参数对应的就是doc_count,以下请求的排序效果和默认的排序效果是一致
GET /cars/transactions/_search
{"size":0,"aggs":{"popular_colors":{"terms": {"field": "color","order": {             ---表示要对聚合结果做排序"_count": "desc"     ---排序字段是doc_count,顺序是降序}}} }
}# _key:在区间聚合的时候(histogram或者date_histogram),可以根据桶的key做排序:
GET /cars/transactions/_search
{"size": 0,"aggs": {"price": {"histogram": {           ---区间聚合"field": "price",      ---取price字段的值"interval": 20000,     ---每个区间的大小是20000"order": {             ---表示要对聚合结果做排序"_key": "desc"       ---排序字段是桶的key值,这里是每个区间的起始值,顺序是降序}}}}
}
# es返回......"aggregations" : {"price" : {"buckets" : [{"key" : 80000.0,"doc_count" : 1},{"key" : 60000.0,"doc_count" : 0},{"key" : 40000.0,"doc_count" : 0},{"key" : 20000.0,"doc_count" : 4},{"key" : 0.0,"doc_count" : 3}]}}
}

2 nested类型

2.1 一个官网例子

A special single bucket aggregation that enables aggregating nested documents.
For example, lets say we have an index of products, and each product holds the list of resellers - each having its own price for the product. The mapping could look like:

# 可执行
# resellers is an array that holds nested documents.
PUT /products
{"mappings": {"Apple":{"properties" : {"resellers" : { "type" : "nested","properties" : {"reseller" : { "type" : "text" },"price" : { "type" : "double" }}}}}}
}# We are using a dynamic mapping for the name attribute.
PUT /products/Apple/0
{"name": "LED TV", "resellers": [{"reseller": "companyA","price": 350},{"reseller": "companyB","price": 500}]
}# The following request returns the minimum price a product can be purchased for
GET /products/_search
{"size": 0,"query" : {"match" : { "name" : "led tv" }},"aggs" : {"resellers" : {"nested" : {"path" : "resellers"},"aggs" : {"min_price" : { "min" : { "field" : "resellers.price" } }}}}
}

As you can see above, the nested aggregation requires the path of the nested documents within the top level documents. Then one can define any type of aggregation over these nested documents.

{..."aggregations": {"resellers": {"doc_count": 2,"min_price": {"value": 350}

参考资料

  1. https://blog.csdn.net/boling_cavalry/article/details/89735952 详细讲解了聚合查询
  2. https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html官网例子

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/420871.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

12 Essential Bootstrap Tools for Web Designers

12 Essential Bootstrap Tools for Web Designers Posted by vikas on June 6, 2014, filed in: Tools, Web Design 原文地址:http://designzum.com/2014/06/06/12-best-bootstrap-tools-for-web-designers/Bootstrap is a great front end website development pla…

关于目录操作walk

对于多级目录的文件处理,walk是神器,一个模板如下: root 所指的是当前正在遍历的这个文件夹的本身的地址dirs 是一个 list ,内容是该文件夹中所有的目录的名字(不包括子目录)files 同样是 list , 内容是该文件夹中所有的文件(不包…

注册COM组件cmd(管理员权限)

比如,注册这个很老版本的office组件 C:\Windows\system32>regsvr32 d:\dsoframer.ocx转载于:https://www.cnblogs.com/3Tai/p/3779696.html

文本处理常用方法

匹配模式字符串不要有任何空格和变量,重要!重要!重要! re 准备正则表达式 在正则表达式中,如果直接给出字符,就是精确匹配。 \d 可以匹配一个数字 \W 匹配非字母数字及下划线 \w 可以匹配一个字母或数字…

Entity Framework中IQueryable, IEnumerable, IList的区别

博客园里有这样的总结。这里姑且先列个题目, 提醒自己记忆。转载于:https://www.cnblogs.com/buguge/p/3779817.html

Java中重载和复写的区别

Java中重载和复写的区别重载(overload)复写(override)区别和联系重载(overload) 函数重载的最突出的例子就是类的构造函数,用户定义一个对象时可能会提供多种参数组合;函数重载的第…

Sublime Text3自定义快捷键

转载于:https://www.cnblogs.com/shimily/articles/3783711.html

打jar包和执行jar包

使用eclipse打jar包 默认生成的目录在/Work/Projects/eclipse-workspace 执行 java -cp hellotest.jar com.feiyangedu.sample.Main java -cp testtesttest.jar com.feiyangedu.sample.Person out:print person java -cp testtesttest.jar com.feiyangedu.sample.…

受限波尔兹曼机

1. 概述 前面描述的神经网络模型是一种确定的结构。而波尔兹曼网络是一种随机网络。如何来描述一个随机网络呢?很多书上有大量的篇幅介绍其原理。这里把它总结为以下两点。 第一,概率分布函数。由于网络节点的取值状态是随机的,从贝叶斯网的…

字符编码理解

计算的本质是二进制的运算,所以要想把现实生活中的文字、图片、语音等信号媒介用计算机来处理,必须把这些东西切分成基本元素,然后把每一个元素一一映射为数字,这是最基本的做法。 英语切分成最基本的元素就是26个字母大小写加上…

jQuery css详解

今天确确实实是放了一天假,喝了点小酒,看了天天向上和快乐大本营以及中国好舞蹈,越来越热爱舞蹈了,还是总结一篇吧。 jquery css css(name|pro|[,val|fn):访问或设置匹配元素的样式属性 1 $("div").click(fu…

1001 害死人不偿命的(3n+1)猜想 (15分)

1001 害死人不偿命的(3n1)猜想 (15分) 卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n1。卡拉…

java中的动态绑定与静态绑定

首先是方法的参数是父类对象,传入子类对象是否可行 然后引出Parent p new Children(); 这句代码不是很理解,google的过程中引出向上转型 要理解向上转型又引出了动态绑定 从动态绑定又引出了静态绑定 程序绑定的概念: 绑定指的是一个方法的…

1002 写出这个数 (20分)

1002 写出这个数 (20分) 读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。 输入格式: 每个测试输入包含 1 个测试用例,即给出自然数 n 的值。这里保证 n 小于 10 ​100 ​​ 。 输出格式: 在一…

ATL和ActiveX做的控件.dll和.ocx最主要的区别(摘录)

楼主是不是说用ATL做的控件和用MFC ActiveX wizard的控件有什么区别吧依存的动态库不一样, 一个是ATL.DLL吧, 一个是MFC42.DLL。 ATL开发的控件代码少,轻便,便于网上发布;MFC开发的控件笨重,但是MFC类库丰富…

1003 我要通过! (20分)

1003 我要通过! (20分) “答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。 得到“答案正确”的条件是:…

推荐20款基于 jQuery CSS 的文本效果插件

jQuery 和 CSS 可以说是设计和开发行业的一次革命。这一切如此简单,快捷的一站式服务。jQuery 允许你在你的网页中添加一些真正令人惊叹的东西而不用付出很大的努力,要感谢那些优秀的 jQuery 插件。 所以今天我们将展示一些很酷的文本效果插件&#xff0…