ElasticSeasrch DSL语言练习
有如下一张表,
CREATE TABLE `hotel` (
`id` bigint(20) NOT NULL COMMENT '酒店id',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店名称',
`address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店地址',
`price` int(10) NOT NULL COMMENT '酒店价格',
`score` int(2) NOT NULL COMMENT '酒店评分',
`brand` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店品牌',
`city` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '所在城市',
`star_name` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '酒店星级,1星到5星,1钻到5钻',
`business` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '商圈',
`latitude` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '纬度',
`longitude` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '经度',
`pic` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '酒店图片',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
文章目录
- ElasticSeasrch DSL语言练习
- 构建mapping
- 导入数据
- 常规查询
- 1. 查询所有价格在100到500之间的酒店,并且品牌为希尔顿,按评分降序排序
- 2. 查询地址中包含“东路”的酒店,但不包括品牌为希尔顿的酒店
- 3. 查询所有评分大于等于45的酒店,且名称中包含“如家”字样。
- 4. 查询城市为“北京”且价格低于300的酒店,返回地址和名称字段。
- 5. 查询所有地址中包含“东路”的酒店,并且业务领域包含“产业园”字样,价格在200到500之间。
- 6. 查询所有评分在40到45之间的酒店,按价格升序排序,并且返回前10条记录
- 7. 查询城市为“北京”且价格大于等于600的酒店,且名称中包含“酒店”字样,品牌不为“希尔顿”
- 8. 查询地址中包含“宝安”的酒店,且评分不低于45,但不包括“喜来登”品牌。
- 9. 查询所有业务领域中包含“京基100”的酒店,返回地址和业务领域字段,并按业务领域的长度排序。
- 10. 查询所有地址中包含“宝安”的酒店,并且评分大于40,按评分和价格的加权平均值排序(评分权重为2,价格权重为1)
- 11. 查询所有价格在100到250之间,且城市为“深圳”的酒店,返回名称、地址、评分、价格字段。
- 12. 查询所有评分大于等于40且品牌为“喜来登”的酒店,地址中包含“东路”的酒店按价格降序排序。
- 13. 查询所有业务领域包含“商圈”的酒店,且价格大于200,并按评分升序和价格升序排序。
- 14. 查询所有评分在40到50之间的酒店,且城市为“北京”或“深圳”,价格不低于150,返回名称和评分字段
- 聚合查询
- 1. **按城市分组,计算每个城市的酒店数量**
- 2. 计算每个品牌的酒店的平均价格
- 3. 按评分区间分组,计算每个评分区间的酒店数量
- 4. 按业务领域分组,计算每个业务领域的最高和最低价格
- 5. 按城市分组,计算每个城市酒店的平均评分
- 6. 按地址的前缀(例如,前3个字符)分组,计算每个前缀的酒店数量
- 7. 计算所有酒店的总数量、最贵的酒店价格和最便宜的酒店价格
- 8. 按评分区间(例如,35-40, 40-45, 45-)分组,计算每个评分区间的酒店数量,并计算每个区间的平均价格
- 9. 按城市和品牌分组,计算每个品牌在每个城市的平均价格
- 10. 按地址的前缀(前3个字符)分组,计算每个前缀的最大和最小评分,并计算评分和价格的差异的平均值
- 11. 计算所有城市的酒店数量,计算每个城市酒店的平均评分,同时计算评分与价格的加权平均值(评分权重为3,价格权重为0.5)
- 12. 按品牌和城市分组,计算每个品牌在每个城市的最大价格、最小价格以及价格的标准差
构建mapping
{
"hotel" : {
"mappings" : {
"properties" : {
"address" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
},
"analyzer" : "ik_max_word"
},
"brand" : {
"type" : "keyword"
},
"business" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
},
"analyzer" : "ik_max_word"
},
"city" : {
"type" : "keyword"
},
"id" : {
"type" : "long"
},
"location" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
},
"analyzer" : "ik_max_word"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
},
"analyzer" : "ik_max_word"
},
"pic" : {
"type" : "keyword",
"index" : false
},
"price" : {
"type" : "long"
},
"score" : {
"type" : "long"
}
}
}
}
}
导入数据
请访问以下项目(github地址)获取测试数据,帮将数据导入到ES中
常规查询
1. 查询所有价格在100到500之间的酒店,并且品牌为希尔顿,按评分降序排序
POST hotel/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"price": {
"gte": 100,
"lte": 500
}
}
},
{
"term": {
"brand": "希尔顿"
}
}
]
}
},
"sort": [
{
"score": {
"order": "desc"
}
}
]
}
2. 查询地址中包含“东路”的酒店,但不包括品牌为希尔顿的酒店
POST hotel/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"address": "东路"
}
}
],
"must_not": [
{
"term": {
"brand": "希尔顿"
}
}
]
}
}
}
3. 查询所有评分大于等于45的酒店,且名称中包含“如家”字样。
POST hotel/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"score": {
"gte": 45
}
}
},
{
"match": {
"name": "如家"
}
}
]
}
}
}
4. 查询城市为“北京”且价格低于300的酒店,返回地址和名称字段。
POST hotel/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"city": "北京"
}
},
{
"range": {
"price": {
"lt": 300
}
}
}
]
}
},
"_source": ["name","address"]
}
5. 查询所有地址中包含“东路”的酒店,并且业务领域包含“产业园”字样,价格在200到500之间。
POST hotel/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"address": "东路"
}
},
{
"match": {
"business": "产业园"
}
},
{
"range": {
"price": {
"gte": 200,
"lte": 500
}
}
}
]
}
}
}
6. 查询所有评分在40到45之间的酒店,按价格升序排序,并且返回前10条记录
POST hotel/_search
{
"query": {
"range": {
"score": {
"gte": 40,
"lte": 45
}
}
},
"sort": [
{
"price": {
"order": "asc"
}
}
],
"size": 10
}
7. 查询城市为“北京”且价格大于等于600的酒店,且名称中包含“酒店”字样,品牌不为“希尔顿”
POST hotel/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"city": "北京"
}
},
{
"range": {
"price": {
"gte": 600
}
}
},
{
"match": {
"name": "酒店"
}
}
],
"must_not": [
{
"term": {
"brand": "希尔顿"
}
}
]
}
}
}
8. 查询地址中包含“宝安”的酒店,且评分不低于45,但不包括“喜来登”品牌。
POST hotel/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"address": "宝安"
}
},
{
"range": {
"score": {
"gte": 45
}
}
}
],
"must_not": [
{
"term": {
"brand": {
"value": "喜来登"
}
}
}
]
}
}
}
9. 查询所有业务领域中包含“京基100”的酒店,返回地址和业务领域字段,并按业务领域的长度排序。
POST hotel/_search
{
"query": {
"match_phrase": {
"business": "京基100"
}
},
"_source": ["address","business"],
"sort": [
{
"_script": {
"type" : "number",
"script": {
"source" : "doc['business.keyword'].value.length()"
},
"order": "asc"
}
}
]
}
10. 查询所有地址中包含“宝安”的酒店,并且评分大于40,按评分和价格的加权平均值排序(评分权重为2,价格权重为1)
POST hotel/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"address": "宝安"
}
},
{
"range": {
"score": {
"gt": 40
}
}
}
]
}
},
"sort": [
{
"_script": {
"type" : "number",
"script" : {
"source" : "doc['score'].value * 2 + doc['price'].value * 1"
},
"order": "asc"
}
}
]
}
11. 查询所有价格在100到250之间,且城市为“深圳”的酒店,返回名称、地址、评分、价格字段。
POST hotel/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"price": {
"gte": 100,
"lte": 250
}
}
},
{
"term": {
"city": {
"value": "深圳"
}
}
}
]
}
},
"_source": ["name","address","score","price"]
}
12. 查询所有评分大于等于40且品牌为“喜来登”的酒店,地址中包含“东路”的酒店按价格降序排序。
POST hotel/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"score": {
"gt": 40
}
}
},
{
"term": {
"brand": {
"value": "喜来登"
}
}
},
{
"match": {
"address": "东路"
}
}
]
}
},
"sort": [
{
"price": {
"order": "desc"
}
}
]
}
13. 查询所有业务领域包含“商圈”的酒店,且价格大于200,并按评分升序和价格升序排序。
POST hotel/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"business": "商圈"
}
},
{
"range": {
"price": {
"gt": 200
}
}
}
]
}
},
"sort": [
{
"score": {
"order": "asc"
}
},
{
"price": {
"order": "asc"
}
}
]
}
14. 查询所有评分在40到50之间的酒店,且城市为“北京”或“深圳”,价格不低于150,返回名称和评分字段
POST hotel/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"score": {
"gte": 40,
"lte": 50
}
}
},
{
"range": {
"price": {
"gt": 150
}
}
},
{
"query_string": {
"default_field": "city",
"query": "北京 OR 深圳"
}
}
]
}
},
"_source": ["name","score"]
}
聚合查询
1. 按城市分组,计算每个城市的酒店数量
POST hotel/_search
{
"size": 0,
"aggs": {
"bucket_city": {
"terms": {
"field": "city",
"size": 3
}
}
}
}
"buckets" : [
{
"key" : "上海",
"doc_count" : 83
},
{
"key" : "北京",
"doc_count" : 62
},
{
"key" : "深圳",
"doc_count" : 56
}
]
2. 计算每个品牌的酒店的平均价格
POST hotel/_search
{
"size": 0,
"aggs": {
"bucket_brand": {
"terms": {
"field": "brand"
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
"bucket_brand" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 39,
"buckets" : [
{
"key" : "7天酒店",
"doc_count" : 30,
"avg_price" : {
"value" : 446.46666666666664
}
},
{
"key" : "如家",
"doc_count" : 30,
"avg_price" : {
"value" : 253.2
}
},
{
"key" : "皇冠假日",
"doc_count" : 17,
"avg_price" : {
"value" : 1036.0
}
},
{
"key" : "速8",
"doc_count" : 15,
"avg_price" : {
"value" : 369.0
}
},
{
"key" : "万怡",
"doc_count" : 13,
"avg_price" : {
"value" : 689.1538461538462
}
},
{
"key" : "华美达",
"doc_count" : 13,
"avg_price" : {
"value" : 620.6923076923077
}
},
{
"key" : "和颐",
"doc_count" : 12,
"avg_price" : {
"value" : 455.9166666666667
}
},
{
"key" : "万豪",
"doc_count" : 11,
"avg_price" : {
"value" : 778.3636363636364
}
},
{
"key" : "喜来登",
"doc_count" : 11,
"avg_price" : {
"value" : 1851.1818181818182
}
},
{
"key" : "希尔顿",
"doc_count" : 10,
"avg_price" : {
"value" : 1085.8
}
}
]
}
}
3. 按评分区间分组,计算每个评分区间的酒店数量
POST hotel/_search
{
"size": 0,
"aggs": {
"rangs_score": {
"range": {
"field": "score",
"ranges": [
{
"key": "0到10",
"from": 0,
"to": 10
},
{
"key": "10到20",
"from": 10,
"to": 20
},
{
"key": "2到30",
"from": 20,
"to": 30
},
{
"key": "30到40",
"from": 30,
"to": 40
},
{
"key": "大于40",
"from": 40
}
]
}
}
}
}
"aggregations" : {
"rangs_score" : {
"buckets" : [
{
"key" : "0到10",
"from" : 0.0,
"to" : 10.0,
"doc_count" : 0
},
{
"key" : "10到20",
"from" : 10.0,
"to" : 20.0,
"doc_count" : 0
},
{
"key" : "2到30",
"from" : 20.0,
"to" : 30.0,
"doc_count" : 0
},
{
"key" : "30到40",
"from" : 30.0,
"to" : 40.0,
"doc_count" : 42
},
{
"key" : "大于40",
"from" : 40.0,
"doc_count" : 159
}
]
}
}
4. 按业务领域分组,计算每个业务领域的最高和最低价格
POST hotel/_search
{
"size": 0,
"aggs": {
"bucket_business": {
"terms": {
"field": "business.keyword",
"size": 3
},
"aggs": {
"max_price": {
"max": {
"field": "price"
}
},
"min_price": {
"min": {
"field": "price"
}
}
}
}
}
}
"bucket_business" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 187,
"buckets" : [
{
"key" : "浦东金桥地区",
"doc_count" : 5,
"max_price" : {
"value" : 891.0
},
"min_price" : {
"value" : 218.0
}
},
{
"key" : "科技园",
"doc_count" : 5,
"max_price" : {
"value" : 508.0
},
"min_price" : {
"value" : 198.0
}
},
{
"key" : "嘉定新城",
"doc_count" : 4,
"max_price" : {
"value" : 1286.0
},
"min_price" : {
"value" : 328.0
}
}
]
}
}
5. 按城市分组,计算每个城市酒店的平均评分
POST hotel/_search
{
"size": 0,
"aggs": {
"bucket_city": {
"terms": {
"field": "city"
},
"aggs": {
"avg_score": {
"avg": {
"field": "score"
}
}
}
}
}
}
"aggregations" : {
"bucket_city" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "上海",
"doc_count" : 83,
"avg_score" : {
"value" : 43.33734939759036
}
},
{
"key" : "北京",
"doc_count" : 62,
"avg_score" : {
"value" : 43.46774193548387
}
},
{
"key" : "深圳",
"doc_count" : 56,
"avg_score" : {
"value" : 43.964285714285715
}
}
]
}
}
6. 按地址的前缀(例如,前3个字符)分组,计算每个前缀的酒店数量
POST hotel/_search
{
"size": 0,
"aggs": {
"bucket_address_prefix": {
"terms": {
"field": "address.keyword",
"script": {
"source": "doc['address.keyword'].value.substring(0,3)"
},
"size": 10
}
}
}
}
"aggregations" : {
"bucket_address_prefix" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 178,
"buckets" : [
{
"key" : "罗湖区",
"doc_count" : 4
},
{
"key" : "朝阳北",
"doc_count" : 3
},
{
"key" : "三间房",
"doc_count" : 2
},
{
"key" : "南山区",
"doc_count" : 2
},
{
"key" : "宝安区",
"doc_count" : 2
},
{
"key" : "新金桥",
"doc_count" : 2
},
{
"key" : "沪南公",
"doc_count" : 2
},
{
"key" : "浦建路",
"doc_count" : 2
},
{
"key" : "海淀北",
"doc_count" : 2
},
{
"key" : "清河小",
"doc_count" : 2
}
]
}
}
7. 计算所有酒店的总数量、最贵的酒店价格和最便宜的酒店价格
POST hotel/_search
{
"size": 0,
"aggs": {
"total_count": {
"value_count": {
"field": "id"
}
},
"max_price" : {
"max": {
"field": "price"
}
},
"min_price" : {
"min": {
"field": "price"
}
}
}
}
8. 按评分区间(例如,35-40, 40-45, 45-)分组,计算每个评分区间的酒店数量,并计算每个区间的平均价格
POST hotel/_search
{
"size": 0,
"aggs": {
"rangs_score": {
"range": {
"field": "score",
"ranges": [
{
"from": 35,
"to": 40
},
{
"from": 40,
"to" : 45
},
{
"from": 45
}
]
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
"aggregations" : {
"rangs_score" : {
"buckets" : [
{
"key" : "35.0-40.0",
"from" : 35.0,
"to" : 40.0,
"doc_count" : 42,
"avg_price" : {
"value" : 550.1666666666666
}
},
{
"key" : "40.0-45.0",
"from" : 40.0,
"to" : 45.0,
"doc_count" : 42,
"avg_price" : {
"value" : 478.0952380952381
}
},
{
"key" : "45.0-*",
"from" : 45.0,
"doc_count" : 117,
"avg_price" : {
"value" : 765.7606837606837
}
}
]
}
}
9. 按城市和品牌分组,计算每个品牌在每个城市的平均价格
POST hotel/_search
{
"size": 0,
"aggs": {
"bucket_by_city": {
"terms": {
"field": "city"
},
"aggs": {
"bucket_by_brand": {
"terms": {
"field": "brand",
"size": 3
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
}
}
"aggregations" : {
"bucket_by_city" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "上海",
"doc_count" : 83,
"bucket_by_brand" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 53,
"buckets" : [
{
"key" : "7天酒店",
"doc_count" : 10,
"avg_price" : {
"value" : 286.1
}
},
{
"key" : "万怡",
"doc_count" : 10,
"avg_price" : {
"value" : 714.6
}
},
{
"key" : "如家",
"doc_count" : 10,
"avg_price" : {
"value" : 247.1
}
}
]
}
},
{
"key" : "北京",
"doc_count" : 62,
"bucket_by_brand" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 32,
"buckets" : [
{
"key" : "7天酒店",
"doc_count" : 10,
"avg_price" : {
"value" : 570.9
}
},
{
"key" : "和颐",
"doc_count" : 10,
"avg_price" : {
"value" : 462.6
}
},
{
"key" : "如家",
"doc_count" : 10,
"avg_price" : {
"value" : 339.1
}
}
]
}
},
{
"key" : "深圳",
"doc_count" : 56,
"bucket_by_brand" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 26,
"buckets" : [
{
"key" : "7天酒店",
"doc_count" : 10,
"avg_price" : {
"value" : 482.4
}
},
{
"key" : "如家",
"doc_count" : 10,
"avg_price" : {
"value" : 173.4
}
},
{
"key" : "汉庭",
"doc_count" : 10,
"avg_price" : {
"value" : 343.8
}
}
]
}
}
]
}
}
10. 按地址的前缀(前3个字符)分组,计算每个前缀的最大和最小评分,并计算评分和价格的差异的平均值
POST hotel/_search
{
"size": 0,
"aggs": {
"address_prefixes": {
"terms": {
"field": "address.keyword",
"script": {
"source": "doc['address.keyword'].value.substring(0, 3)"
},
"size": 3
},
"aggs": {
"max_score": {
"max": {
"field": "score"
}
},
"min_score": {
"min": {
"field": "score"
}
},
"average_price" : {
"avg": {
"field": "price"
}
},
"score_price_diff_avg": {
"bucket_script": {
"buckets_path": {
"maxScore": "max_score",
"minScore": "min_score",
"priceAvg": "average_price"
},
"script": "params.maxScore - params.minScore + params.priceAvg"
}
}
}
}
}
}
"aggregations" : {
"address_prefixes" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 192,
"buckets" : [
{
"key" : "罗湖区",
"doc_count" : 4,
"max_score" : {
"value" : 43.0
},
"average_price" : {
"value" : 443.25
},
"min_score" : {
"value" : 39.0
},
"score_price_diff_avg" : {
"value" : 447.25
}
},
{
"key" : "朝阳北",
"doc_count" : 3,
"max_score" : {
"value" : 47.0
},
"average_price" : {
"value" : 425.0
},
"min_score" : {
"value" : 36.0
},
"score_price_diff_avg" : {
"value" : 436.0
}
},
{
"key" : "三间房",
"doc_count" : 2,
"max_score" : {
"value" : 47.0
},
"average_price" : {
"value" : 290.0
},
"min_score" : {
"value" : 47.0
},
"score_price_diff_avg" : {
"value" : 290.0
}
}
]
}
}
11. 计算所有城市的酒店数量,计算每个城市酒店的平均评分,同时计算评分与价格的加权平均值(评分权重为3,价格权重为0.5)
POST hotel/_search
{
"size": 0,
"aggs": {
"bucket_city": {
"terms": {
"field": "city"
},
"aggs": {
"total_count": {
"value_count": {
"field": "id"
}
},
"avg_score" : {
"avg": {
"field": "score"
}
},
"avg_price" : {
"avg": {
"field": "price"
}
},
"avg_weight_price_score" : {
"bucket_script": {
"buckets_path": {
"avgScore" : "avg_score",
"avgPrice" : "avg_price"
},
"script": "params.avgScore * 3 + params.avgPrice * 0.5"
}
}
}
}
}
}
"aggregations" : {
"bucket_city" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "上海",
"doc_count" : 83,
"total_count" : {
"value" : 83
},
"avg_price" : {
"value" : 879.8674698795181
},
"avg_score" : {
"value" : 43.33734939759036
},
"avg_weight_price_score" : {
"value" : 569.9457831325301
}
},
{
"key" : "北京",
"doc_count" : 62,
"total_count" : {
"value" : 62
},
"avg_price" : {
"value" : 545.3548387096774
},
"avg_score" : {
"value" : 43.46774193548387
},
"avg_weight_price_score" : {
"value" : 403.08064516129036
}
},
{
"key" : "深圳",
"doc_count" : 56,
"total_count" : {
"value" : 56
},
"avg_price" : {
"value" : 463.2142857142857
},
"avg_score" : {
"value" : 43.964285714285715
},
"avg_weight_price_score" : {
"value" : 363.5
}
}
]
}
}
12. 按品牌和城市分组,计算每个品牌在每个城市的最大价格、最小价格以及价格的标准差
POST hotel/_search
{
"size": 0,
"aggs": {
"by_city": {
"terms": {
"field": "city"
},
"aggs": {
"by_brand": {
"terms": {
"field": "brand",
"size": 3
},
"aggs": {
"max_price": {
"max": {
"field": "price"
}
},
"min_price": {
"min": {
"field": "price"
}
},
"price_std_dev": {
"extended_stats": {
"field": "price"
}
}
}
}
}
}
}
}