使用阿里云试用Elasticsearch学习:5. 地理位置

news2024/11/27 1:02:22

我们拿着纸质地图漫步城市的日子一去不返了。得益于智能手机,我们现在总是可以知道 自己所处的准确位置,也预料到网站会使用这些信息。我想知道从当前位置步行 5 分钟内可到的那些餐馆,对伦敦更大范围内的其他餐馆并不感兴趣。

但地理位置功能仅仅是 Elasticsearch 的冰山一角,Elasticsearch 的妙处在于,它让你可以把地理位置、全文搜索、结构化搜索和分析结合到一起。

例如:告诉我提到 vitello tonnato 这种食物、步行 5 分钟内可到、且晚上 11 点还营业的餐厅,然后结合用户评价、距离、价格排序。另一个例子:给我展示一幅整个城市8月份可用假期出租物业的地图,并计算出每个区域的平均价格。

Elasticsearch 提供了 两种表示地理位置的方式:用纬度-经度表示的坐标点使用 geo_point 字段类型, 以 GeoJSON 格式定义的复杂地理形状,使用 geo_shape 字段类型。

Geo-points 允许你找到距离另一个坐标点一定范围内的坐标点、计算出两点之间的距离来排序或进行相关性打分、或者聚合到显示在地图上的一个网格。另一方面,Geo-shapes 纯粹是用来过滤的。它们可以用来判断两个地理形状是否有重合或者某个地理形状是否完全包含了其他地理形状。

地理坐标点

地理坐标点 是指地球表面可以用经纬度描述的一个点。 地理坐标点可以用来计算两个坐标间的距离,还可以判断一个坐标是否在一个区域中,或在聚合中。
地理坐标点不能被动态映射(dynamic mapping)自动检测,而是需要显式声明对应字段类型为 geo-point :

PUT /attractions
{
  "mappings": {
    "properties": {
        "name": {
          "type": "text"
        },
        "location": {
          "type": "geo_point"
        }
      }
  }
}

经纬度坐标格式

如上例,location 字段被声明为 geo_point 后,我们就可以索引包含了经纬度信息的文档了。经纬度信息的形式可以是字符串、数组或者对象:

PUT /attractions/_doc/1
{
  "name":     "Chipotle Mexican Grill",
  "location": "40.715, -74.011" 
}

PUT /attractions/_doc/2
{
  "name":     "Pala Pizza",
  "location": { 
    "lat":     40.722,
    "lon":    -73.989
  }
}

PUT /attractions/_doc/3
{
  "name":     "Mini Munchies Pizza",
  "location": [ -73.983, 40.719 ] 
}
  • 字符串形式以半角逗号分割,如 “lat,lon” 。
  • 对象形式显式命名为 lat 和 lon 。
  • 数组形式表示为 [lon,lat] 。

可能所有人都至少一次踩过这个坑:地理坐标点用字符串形式表示时是纬度在前,经度在后( “latitude,longitude” ),而数组形式表示时是经度在前,纬度在后( [longitude,latitude] )—顺序刚好相反。
其实,在 Elasticesearch 内部,不管字符串形式还是数组形式,都是经度在前,纬度在后。不过早期为了适配 GeoJSON 的格式规范,调整了数组形式的表示方式。
因此,在使用地理位置的路上就出现了这么一个“捕熊器”,专坑那些不了解这个陷阱的使用者。

通过地理坐标点过滤

有四种地理坐标点相关的过滤器可以用来选中或者排除文档:

geo_bounding_box
找出落在指定矩形框中的点。
geo_distance
找出与指定位置在给定距离内的点。
geo_distance_range
找出与指定点距离在给定最小距离和最大距离之间的点。
geo_polygon
找出落在多边形中的点。 这个过滤器使用代价很大 。当你觉得自己需要使用它,最好先看看 geo-shapes 。

这些过滤器判断点是否落在指定区域时的计算方法稍有不同,但过程类似。指定的区域被转换成一系列以quad/geohash为前缀的tokens,并被用来在倒排索引中搜索拥有相同tokens的文档。

地理坐标过滤器使用代价昂贵 — 所以最好在文档集合尽可能少的场景下使用。你可以先使用那些简单快捷的过滤器,比如 term 或 range ,来过滤掉尽可能多的文档,最后才交给地理坐标过滤器处理。
布尔型过滤器 bool filter 会自动帮你做这件事。它会优先让那些基于“bitset”的简单过滤器(见 关于缓存 )来过滤掉尽可能多的文档,然后依次才是更昂贵的地理坐标过滤器或者脚本类的过滤器。

地理坐标盒模型过滤器

这是目前为止最有效的地理坐标过滤器了,因为它计算起来非常简单。 你指定一个矩形的 顶部 , 底部 , 左边界 ,和 右边界 ,然后过滤器只需判断坐标的经度是否在左右边界之间,纬度是否在上下边界之间:

GET attractions/_search
{
  "query": {
    "bool": {
      "filter": {
        "geo_bounding_box": {
          "location": {
            "top_left": {
              "lat": 40.8,
              "lon": -74
            },
            "bottom_right": {
              "lat": 40.7,
              "lon": -73
            }
          }
        }
      }
    }
  }
}
  • 这些坐标也可以用 bottom_left 和 top_right 来表示。

地理距离过滤器

地理距离过滤器( geo_distance )以给定位置为圆心画一个圆,来找出那些地理坐标落在其中的文档:

GET /attractions/_search
{
  "query": {
    "bool": {
      "filter": {
        "geo_distance": {
          "distance": "1km",
          "location": {
            "lat": 40.715,
            "lon": -73.988
          }
        }
      }
    }
  }
}
  • 找出所有与指定点距离在 1km 内的 location 字段。访问 Distance Units 查看所支持的距离表示单位。
  • 中心点可以表示为字符串,数组或者(如示例中的)对象。详见 经纬度坐标格式。

地理距离过滤器计算代价昂贵。为了优化性能,Elasticsearch 先画一个矩形框来围住整个圆形,这样就可以先用消耗较少的盒模型计算方式来排除掉尽可能多的文档。 然后只对落在盒模型内的这部分点用地理距离计算方式处理。

你需要判断你的用户,是否需要如此精确的使用圆模型来做距离过滤?通常使用矩形模型 bounding box 是比地理距离更高效的方式,并且往往也能满足应用需求。

更快的地理距离计算

两点间的距离计算,有多种牺牲性能换取精度的算法:

arc
最慢但最精确的是 arc 计算方式,这种方式把世界当作球体来处理。不过这种方式的精度有限,因为这个世界并不是完全的球体。
plane
plane 计算方式把地球当成是平坦的,这种方式快一些但是精度略逊。在赤道附近的位置精度最好,而靠近两极则变差。
sloppy_arc
如此命名,是因为它使用了 Lucene 的 SloppyMath 类。这是一种用精度换取速度的计算方式, 它使用 Haversine formula 来计算距离。它比 arc 计算方式快 4 到 5 倍,并且距离精度达 99.9%。这也是默认的计算方式。

你可以参考下例来指定不同的计算方式:

GET /attractions/_search
{
  "query": {
    "bool": {
      "filter": {
        "geo_distance": {
          "distance": "1km",
          "distance_type": "plane",
          "location": {
            "lat": 40.715,
            "lon": -73.988
          }
        }
      }
    }
  }
}
  • 使用更快但精度稍差的 plane 计算方法。

你的用户真的会在意一个餐馆落在指定圆形区域数米之外吗?一些地理位置相关的应用会有较高的精度要求;但大部分实际应用场景中,使用精度较低但响应更快的计算方式可能更好。

按距离排序

检索结果可以按与指定点的距离排序:

GET /attractions/_search
{
  "query": {
    "bool": {
      "filter": {
        "geo_bounding_box": {
          "location": {
            "top_left": {
              "lat": 40.8,
              "lon": -74
            },
            "bottom_right": {
              "lat": 40.4,
              "lon": -73
            }
          }
        }
      }
    }
  },
  "sort": [
    {
      "_geo_distance": {
        "location": {
          "lat": 40.715,
          "lon": -73.998
        },
        "order": "asc",
        "unit": "km",
        "distance_type": "plane"
      }
    }
  ]
}
  • 计算每个文档中 location 字段与指定的 lat/lon 点间的距离。
  • 将距离以 km 为单位写入到每个返回结果的 sort 键中。
  • 使用快速但精度略差的 plane 计算方式。

你可能想问:为什么要制定距离的 单位 呢?用于排序的话,我们并不关心比较距离的尺度是英里、公里还是光年。 原因是,这个用于排序的值会设置在每个返回结果的 sort 元素中。

"hits": [
      {
        "_index": "attractions",
        "_id": "2",
        "_score": null,
        "_source": {
          "name": "Pala Pizza",
          "location": {
            "lat": 40.722,
            "lon": -73.989
          }
        },
        "sort": [
          1.0868108882400258
        ]
      },

Geohashes

Geohashes 是一种将经纬度坐标( lat/lon )编码成字符串的方式。这么做的初衷只是为了让地理位置在 url 上呈现的形式更加友好,但现在 geohashes 已经变成一种在数据库中有效索引地理坐标点和地理形状的方式。

Geohashes 把整个世界分为 32 个单元的格子 —— 4 行 8 列 —— 每一个格子都用一个字母或者数字标识。比如 g 这个单元覆盖了半个格林兰,冰岛的全部和大不列颠的大部分。每一个单元还可以进一步被分解成新的 32 个单元,这些单元又可以继续被分解成 32 个更小的单元,不断重复下去。 gc 这个单元覆盖了爱尔兰和英格兰, gcp 覆盖了伦敦的大部分和部分南英格兰, gcpuuz94k 是白金汉宫的入口,精确到约 5 米。

换句话说, geohash 的长度越长,它的精度就越高。如果两个 geohashes 有一个共同的前缀— gcpuuz—就表示他们挨得很近。共同的前缀越长,距离就越近。

这也意味着,两个刚好相邻的位置,可能会有完全不同的 geohash 。比如,伦敦 Millenium Dome 的 geohash 是 u10hbp ,因为它落在了 u 这个单元里,而紧挨着它东边的最大的单元是 g 。

地理坐标点可以自动索引相关的 geohashes ,更重要的是,他们也可以索引所有的 geohashes 前缀 。如索引白金汉宫入口位置——纬度 51.501568 ,经度 -0.141257—将会索引下面表格中列出的所有 geohashes ,表格中也给出了各个 geohash 单元的近似尺寸:


Geohash			Level		Dimensions
g				1			~ 5,004km x 5,004km
gc				2			~ 1,251km x 625km
...				...			...
gcpuuz94		8			~ 38.2m x 19.1m
gcpuuz94k		9			~ 4.78m x 4.78m
...				...			...
gcpuuz94kkp5	12			~ 3.7cm x 1.8cm

geohash单元 过滤器 可以使用这些 geohash 前缀来找出与指定坐标点( lat/lon )相邻的位置。

Geohashes 映射

首先,你需要决定使用什么样的精度。虽然你也可以使用 12 级的精度来索引所有的地理坐标点,但是你真的需要精确到数厘米吗?如果你把精度控制在一个实际一些的值,比如 1km ,那么你可以节省大量的索引空间:

PUT /museums
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_point"
      }
    }
  }
}

POST /museums/_bulk?refresh
{"index":{"_id":1}}
{"location": "POINT (4.912350 52.374081)", "name": "NEMO Science Museum"}
{"index":{"_id":2}}
{"location": "POINT (4.901618 52.369219)", "name": "Museum Het Rembrandthuis"}
{"index":{"_id":3}}
{"location": "POINT (4.914722 52.371667)", "name": "Nederlands Scheepvaartmuseum"}
{"index":{"_id":4}}
{"location": "POINT (4.405200 51.222900)", "name": "Letterenhuis"}
{"index":{"_id":5}}
{"location": "POINT (2.336389 48.861111)", "name": "Musée du Louvre"}
{"index":{"_id":6}}
{"location": "POINT (2.327000 48.860000)", "name": "Musée d'Orsay"}

POST /museums/_search?size=0
{
  "aggregations": {
    "large-grid": {
      "geohash_grid": {
        "field": "location",
        "precision": 3
      }
    }
  }
}

Response:

{
  ...
  "aggregations": {
  "large-grid": {
    "buckets": [
      {
        "key": "u17",
        "doc_count": 3
      },
      {
        "key": "u09",
        "doc_count": 2
      },
      {
        "key": "u15",
        "doc_count": 1
      }
    ]
  }
}
}

在这里插入图片描述

地理位置聚合

虽然按照地理位置对结果进行过滤或者打分很有用, 但是在地图上呈现信息给用户通常更加有用。一个查询可能会返回太多结果以至于不能单独地展现每一个地理坐标点,但是地理位置聚合可以用来将地理坐标聚集到更加容易管理的 buckets 中。
处理 geo_point 类型字段的三种聚合:

地理位置距离
将文档按照距离围绕一个中心点来分组。
geohash 网格
将文档按照 geohash 范围来分组,用来显示在地图上。
地理位置边界
返回一个包含所有地理位置坐标点的边界的经纬度坐标,这对显示地图时缩放比例的选择非常有用。

地理距离聚合

geo_distance 聚合 对一些搜索非常有用,例如找到所有距离我 1km 以内的披萨店。搜索结果应该也的确被限制在用户指定 1km 范围内,但是我们可以添加在 2km 范围内找到的其他结果:

GET /attractions/_search
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "name": "pizza"
        }
      },
      "filter": {
        "geo_bounding_box": {
          "location": {
            "top_left": {
              "lat": 40.8,
              "lon": -74.1
            },
            "bottom_right": {
              "lat": 40.4,
              "lon": -73.7
            }
          }
        }
      }
    }
  },
  "aggs": {
    "per_ring": {
      "geo_distance": {
        "field": "location",
        "unit": "km",
        "origin": {
          "lat": 40.712,
          "lon": -73.988
        },
        "ranges": [
          {
            "from": 0,
            "to": 1
          },
          {
            "from": 1,
            "to": 2
          }
        ]
      }
    }
  },
  "post_filter": {
    "geo_distance": {
      "distance": "1km",
      "location": {
        "lat": 40.712,
        "lon": -73.988
      }
    }
  }
}
  • 主查询查找名称中含有 pizza 的饭店。
  • geo_bounding_box 筛选那些只在纽约区域的结果。
  • geo_distance 聚合统计距离用户 1km 以内,1km 到 2km 的结果的数量。
  • 最后,post_filter 将结果缩小至那些在用户 1km 范围内的饭店。
{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.4471386,
    "hits": [
      {
        "_index": "attractions",
        "_id": "3",
        "_score": 0.4471386,
        "_source": {
          "name": "Mini Munchies Pizza",
          "location": [
            -73.983,
            40.719
          ]
        }
      }
    ]
  },
  "aggregations": {
    "per_ring": {
      "buckets": [
        {
          "key": "*-1.0",
          "from": 0,
          "to": 1,
          "doc_count": 1
        },
        {
          "key": "1.0-2.0",
          "from": 1,
          "to": 2,
          "doc_count": 1
        }
      ]
    }
  }
}
  • post_filter 已经将搜索结果缩小至仅在用户 1km 范围以内的披萨店。
  • 聚合包括搜索结果加上其他在用户 2km 范围以内的披萨店。

在这个例子中,我们计算了落在每个同心环内的饭店数量。当然,我们可以在 per_rings 聚合下面嵌套子聚合来计算每个环的平均价格、最受欢迎程度,等等。

Geohash 网格聚合

通过一个查询返回的结果数量对在地图上单独的显示每一个位置点而言可能太多了。 geohash_grid 按照你定义的精度计算每一个点的 geohash 值而将附近的位置聚合在一起。

结果是一个网格—一个单元格表示一个可以显示在地图上的 geohash 。通过改变 geohash 的精度,你可以按国家或者城市街区来概括全世界。

聚合是稀疏的—它 仅返回那些含有文档的单元。 如果 geohashes 太精确,将产生太多的 buckets,它将默认返回那些包含了大量文档、最密集的10000个单元。 然而,为了计算哪些是最密集的 Top10000 ,它还是需要产生 所有 的 buckets 。可以通过以下方式来控制 buckets 的产生数量:

  1. 使用 geo_bounding_box 来限制结果。
  2. 为你的边界大小选择一个适当的 precision (精度)
GET /attractions/_search
{
  "size" : 0,
  "query": {
    "constant_score": {
      "filter": {
        "geo_bounding_box": {
          "location": { 
            "top_left": {
              "lat":  40.8,
              "lon": -74.1
            },
            "bottom_right": {
              "lat":  40.4,
              "lon": -73.7
            }
          }
        }
      }
    }
  },
  "aggs": {
    "new_york": {
      "geohash_grid": { 
        "field":     "location",
        "precision": 5
      }
    }
  }
}
  • 边界框将搜索限制在大纽约区的范围
  • Geohashes 精度为 5 大约是 5km x 5km。

Geohashes 精度为 5 ,每个约25平方公里,所以10000个单元按这个精度将覆盖250000平方公里。我们指定的边界范围,约44km x 33km,或约1452平方公里,所以我们的边界在安全范围内;我们绝对不会在内存中创建了太多的 buckets。

前面的请求响应看起来是这样的:

"aggregations": {
    "new_york": {
      "buckets": [
        {
          "key": "dr5rs",
          "doc_count": 2
        },
        {
          "key": "dr5re",
          "doc_count": 1
        }
      ]
    }
  }
  • 每个 bucket 包含作为 key 的 geohash 值

同样,我们也没有指定任何子聚合,所以我们得到是文档计数。如果需要,我们也可以了解这些 buckets 中受欢迎的餐厅类型、平均价格或其他细节。

地理形状

地理形状( Geo-shapes )使用一种与地理坐标点完全不同的方法。我们在计算机屏幕上看到的圆形并不是由完美的连续的线组成的。而是用一个个连续的着色像素点画出的一个近似圆。地理形状的工作方式就与此相似。

复杂的形状——比如点集、线、多边形、多多边形、中空多边形——都是通过 geohash 单元 “画出来” 的,这些形状会转化为一个被它所覆盖到的 geohash 的集合。

实际上,两种类型的网格可以被用于 geo-shapes:默认使用我们之前讨论过的 geohash ,另外还有一种是 四叉树 。四叉树与 geohash 类似,除了四叉树每个层级只有 4 个单元,而不是 32 。这种不同取决于编码方式的选择。

组成一个形状的 geohash 都作为一个单元被索引在一起。有了这些信息,通过查看是否有相同的 geohash 单元,就可以很轻易地检查两个形状是否有交集。

geo-shapes 有以下作用:判断查询的形状与索引的形状的关系;这些 关系 可能是以下之一:

intersects
查询的形状与索引的形状有重叠(默认)。
disjoint
查询的形状与索引的形状完全 不 重叠。
within
索引的形状完全被包含在查询的形状中。

Geo-shapes 不能用于计算距离、排序、打分以及聚合。

索引地理形状

地理形状通过 GeoJSON 来表示,这是一种开放的使用 JSON 实现的二维形状编码方式。 每个形状都包含了形状类型— point, line, polygon, envelope —和一个或多个经纬度点集合的数组。

如,我们用一个多边形来索引阿姆斯特丹达姆广场:

PUT /attractions
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "location": {
        "type": "geo_shape"
      }
    }
  }
}
PUT /attractions/_doc/dam_square
{
    "name" : "Dam Square, Amsterdam",
    "location" : {
        "type" : "polygon", 
        "coordinates" : [[ 
          [ 4.89218, 52.37356 ],
          [ 4.89205, 52.37276 ],
          [ 4.89301, 52.37274 ],
          [ 4.89392, 52.37250 ],
          [ 4.89431, 52.37287 ],
          [ 4.89331, 52.37346 ],
          [ 4.89305, 52.37326 ],
          [ 4.89218, 52.37356 ]
        ]]
    }
}
  • type 参数指明了经纬度坐标集表示的形状类型。
  • lon/lat 列表描述了多边形的形状。
上例中大量的方括号可能看起来让人困惑,不过实际上 GeoJSON 的语法非常简单:

用一个数组表示 经纬度 坐标点:

[lon,lat]
一组坐标点放到一个数组来表示一个多边形:

[[lon,lat],[lon,lat], ... ]
一个多边形( polygon )形状可以包含多个多边形;第一个表示多边形的外轮廓,后续的多边形表示第一个多边形内部的空洞:

[
  [[lon,lat],[lon,lat], ... ],  # main polygon
  [[lon,lat],[lon,lat], ... ],  # hole in main polygon
  ...
]

参考

查询地理形状

geo_shape 查询不寻常的地方在于,它允许我们使用形状来做查询,而不仅仅是坐标点。

举个例子,当我们的用户刚刚迈出阿姆斯特丹中央火车站时,我们可以用如下方式,查询出方圆 1km 内的所有地标:

GET /attractions/_search
{
  "query": {
    "geo_shape": {
      "location": { 
        "shape": { 
          "type":   "circle", 
          "radius": "1km",
          "coordinates": [ 
            4.89994,
            52.37815
          ]
        }
      }
    }
  }
}
  • 查询使用 location 字段中的地理形状。
  • 查询中的形状是由 shape 键对应的内容表示。
  • 形状是一个半径为 1km 的圆形。
  • 安姆斯特丹中央火车站入口的坐标点。

默认的,查询(或者过滤器 —— 工作方式相同)会从已索引的形状中寻找与指定形状有交集的部分。此外,可以把 relation 字段设置为 disjoint 来查找与指定形状不相交的部分,或者设置为 within 来查找完全落在查询形状中的。

举个例子,我们可以查找阿姆斯特丹中心区域所有的地标:

GET /attractions/_search
{
  "query": {
    "geo_shape": {
      "location": {
        "relation": "within", 
        "shape": {
          "type": "polygon",
          "coordinates": [[ 
              [4.88330,52.38617],
              [4.87463,52.37254],
              [4.87875,52.36369],
              [4.88939,52.35850],
              [4.89840,52.35755],
              [4.91909,52.36217],
              [4.92656,52.36594],
              [4.93368,52.36615],
              [4.93342,52.37275],
              [4.92690,52.37632],
              [4.88330,52.38617]
            ]]
        }
      }
    }
  }
}
  • 只匹配完全落在查询形状中的已索引的形状。
  • 这个多边形表示安姆斯特丹中心区域。

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

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

相关文章

【Linux】磁盘阵列RAID技术

目录 一、RAID介绍 1.1 什么是RAID技术? 1.2 为什么要使用RAID技术? 二、RAID级别 2.1 常见的RAID级别 2.2 常见RAID介绍 三、RAID特性对比 一、RAID介绍 1.1 什么是RAID技术? 把多块独立的物理磁盘按不同的方式组合起来形成一个硬盘…

基于zookeeper安装Kafka集群

操作系统:centOS 9 Stream,6台,基于vmware虚拟机创建 准备工作 确认系统环境: 确保所有服务器已安装了最新更新。安装Java Development Kit (JDK) 8或更高版本,因为ZooKeeper和Kafka都是基于Java开发的。例如&#x…

【安全】查杀linux挖矿病毒 kswapd0

中毒现象 高cpu占用,使用top命令查看cpu使用率长时间50%以上,cpu占用异常的进程八成就是挖矿病毒进程 此病毒隐藏了自己,top命令无法查看到挖矿病毒进程,可通过sysdig命令找到隐藏进程 安装sysdig curl -s https://s3.amazonaw…

外卖小程序实战-接单后小票机自动打印订单

1、导入小票机的sdk https://www.feieyun.com/api/API-JAVA.zip public static String addprinter(String snlist){//通过POST请求,发送打印信息到服务器RequestConfig requestConfig RequestConfig.custom() .setSocketTimeout(30000)//读取超时 .setConnectTi…

文件读写异常处理(day25)

题目一:文件读写异常处理 要求: 编写一个Java程序,该程序尝试读取一个名为example.txt的文件,并逐行打印其内容到控制台。 如果文件example.txt不存在,程序应捕获FileNotFoundException异常,并输出相应的…

ActiveMQ 任意文件上传漏洞复现

一、使用弱口令登陆 ​ 访问 http://ip:8161/admin/ 进入admin登陆页面,使用弱口令登陆,账号密码皆为 admin,登陆成功后,headers中会出现验证信息 ​ 如: Authorization: Basic YWRtaW46YWRtaW4 # 二、利用PUT协议上…

Docker 入门介绍及简单使用

Docker 的简单介绍 中文官网:Docker中文网 官网 英文官网:Docker: Accelerated Container Application Development Docker 是一个开源的应用容器引擎,它允许开发者打包应用及其依赖包到一个可移植的容器中,然后发布到任何流行的 …

【Java开发指南 | 第八篇】Java变量、构造方法、创建对象

读者可订阅专栏:Java开发指南 |【CSDN秋说】 文章目录 Java变量构造方法创建对象 Java变量 在Java中,变量用于存储数据值。它们是程序中用于保存信息的一种基本方式。变量在程序执行过程中可以被赋予不同的值,并且这些值可以在程序的不同部分…

使用Python模仿文件行为

在Python中,你可以通过文件操作函数(如open()函数)以及模拟输入输出流的库(如io模块)来模拟文件行为。下面是一些示例,展示了如何使用这些工具在Python中模拟文件行为。 1、问题背景 在编写一个脚本时&…

轮胎行业EDI:Tigar 轮胎EDI项目案例

Tigar 轮胎是一家塞尔维亚轮胎制造公司,自2007年开始,被轮胎制造商米其林持有。 Tigar通过EDI来传输与供应商之间的业务单据,优化业务流程。本文将从EDI需求概览、如何基于知行之桥EDI系统实现与Tigar的EDI对接以及项目回顾这三个部分为大家展…

Docker部署MongoDB数据库

文章目录 官网地址docker 网络部署 MongoDB部署 mongo-expressdocker-compose.ymlMongoDB shell 官网地址 https://www.mongodb.com/zh-cn docker 网络 # 创建 mongo_network 网络 docker network create mongo_network # 查看网络 docker network list # 容器连接到 mongo_…

AI智能分析网关V4平台告警数据清理方法:自动清理与手动清理

TSINGSEE青犀智能分析网关V4属于高性能、低功耗的软硬一体AI边缘计算硬件设备,目前拥有3种型号(8路/16路/32路),支持Caffe/DarkNet/TensorFlow/PyTorch/MXNet/ONNX/PaddlePaddle等主流深度学习框架。硬件内部署了近40种AI算法模型…

C语言中的结构体:从定义到传递

前言 结构体是C语言中一种重要的数据类型,它允许我们将不同类型的数据组合成一个整体,并以自定义的方式进行操作。通过结构体,我们可以更加灵活地管理和处理复杂的数据结构,从而提高程序的可读性和可维护性。本篇博客将从结构体的…

allure2教程-1-环境搭建

领取资料,咨询答疑,请➕wei: June__Go 自动化测试执行完成后我们需要展示给其他人看,这就要有自动化测试报告了。复杂的测试报告当然可以自己代码实现,但用pytest-html或allure基本也能满足我们生成测试报告的要求了。本小节介绍…

Rustdesk如何编译代码实现安装后,不会在右下角出现托盘图标

环境: Rustdesk1.1.9 问题描述: Rustdesk如何编译代码实现安装后,不会在右下角出现托盘图标 解决方案: 安装后只有自定义进程图标 详细方案,有需要私聊

Python及软件测试方面的总结的技巧

目录 一.Python (一)输入pip安装包时出现Fatal error in launcher错误 (二)如何使用清华镜像安装库 二.软件测试 一.Python (一)输入pip安装包时出现Fatal error in launcher错误 解决方法&#xff1a…

Linux之bpfjit(2)使用分析和mini-tcpdump实现

Linux之bpfjit(2)使用分析和mini-tcpdump实现 Author: Once Day Date: 2024年4月13日 一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦… 漫漫长路,有人对你微笑过嘛… 全系列文章可以参考专栏:…

简约风好看的个人主页源码

效果图 PC端 移动端 源代码 index.html &#xfeff;<html lang"en"><head><meta charset"utf-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content&quo…

全网短剧搜索源码+短剧API接口 短剧下载 热门短剧 全开源可二开

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 pc端h5手机端全网短剧搜索前端源码分享 内含7000短剧资源(不支持在线播放&#xff09; 搜索API接口&#xff1a;文件内查看 全部短剧API接口&#xff1a;文件内查看 每日更新API接…

48.HarmonyOS鸿蒙系统 App(ArkUI)常用组件的使用

48.HarmonyOS鸿蒙系统 App(ArkUI)常用组件的使用 按钮触发事件 toast信息提示 单选按钮 复选框 切换按钮&#xff0c;开关按钮 进度条 textbox,textinput,TextArea文本输入框 气泡提示 import prompt from ohos.prompt; import promptAction from ohos.promptAction; …