Elasticsearch基础概念和Python操作

python 操作 Elasticsearch(一) python 操作 Elasticsearch(一) 1、python连接elasticsearch数据库 from elasticsearch import Elasticsearch from elasticsearch import helpers es = Elasticsearch(['你的elasticsearch的外网连接'], http_auth=('数据的用户名', '密码')) 阅读详情

一、Elasticsearch 基础概念

1.1 基本概念

Elasticsearch 是一个分布式文档存储。Elasticsearch 不是将信息存储为列式数据行,而是存储已序列化为 JSON 文档的复杂数据结构。当集群中有多个 Elasticsearch 节点时,存储的文档会分布在整个集群中,并且可以从任何节点立即访问。

存储文档后,它会在近乎实时的时间内被索引并完全可搜索——在1 秒内。Elasticsearch 使用一种称为倒排索引的数据结构,它支持非常快速的全文搜索。倒排索引列出了出现在任何文档中的每个唯一单词,并标识了每个单词出现的所有文档。

1.2 REST API

Elasticsearch 提供了一个简单、连贯的 REST API,用于管理集群以及索引和搜索数据。

Elasticsearch REST API 支持结构化查询、全文查询和将两者结合的复杂查询。结构化查询类似于你可以在 SQL 中构造的查询类型。例如,你可以搜索索引中的gender和age字段并按字段employee作为索引,使用hire_date进行排序。全文查询查找与查询字符串匹配的所有文档,并按相关性排序返回它们——它们与你的搜索词的匹配程度。

除了搜索单个术语外,你还可以执行短语搜索、相似性搜索和前缀搜索,并获得自动完成建议。

有要搜索的地理空间或其他数字数据吗?Elasticsearch 在支持高性能地理和数字查询的优化数据结构中索引非文本数据。

您可以使用 Elasticsearch 全面的 JSON 样式查询语言 ( Query DSL ) 访问所有这些搜索功能。您还可以构建SQL 样式的查询以在 Elasticsearch 内本地搜索和聚合数据,而 JDBC 和 ODBC 驱动程序使广泛的第三方应用程序能够通过 SQL 与 Elasticsearch 进行交互。

1.3 数据类型

Elasticsearch 在mappings参数中定义字段的,类似与数据库中的表结构的定义。

Elasticsearch 主要的基本数据类型有:

  1. 字符类型:text、keyword

    • text: 全文搜索,会被分词处理,如果进行聚合、排序计算需要开启fielddata进行内存预加载,不建议此使用方法。
    • keyword:精准值,不会被分词。进行过滤、排序、聚合等操作时, 就应该使用keyword类型。
  2. 数字类型:long、integer、short、byte、double、float、 half_float、 scaled_float

    尽可能选择范围小的数据类型, 字段的长度越短, 索引和搜索的效率越高,尽可能避免浮点类型,如果必须使用优先考虑使用带缩放因子的浮点类型。

  3. 日期:date

    由于json中无日期类型,所以es中日期可能是:

    • 包含格式化日期的字符串, “2018-10-01”, 或"2018/10/01 12:10:30"
    • 代表时间毫秒数的长整型数字
    • 代表时间秒数的整数
    • 注意日期格式

    es系统初始化需要指定时区
    如果时区未指定, 日期将被转换为UTC格式, 但存储的却是长整型的毫秒值.
    可以自定义日期格式, 若未指定, 则使用默认格式: strict_date_optional_time||epoch_millis

    设置多种日期格式

    {
        "mappings": {
            "blog": {
                "properties": {
                    "date": {
                        "type": "date",  // 可以接受如下类型的格式
                        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
                    }
                }
            }
        }
    }
    
  4. 日期 纳秒:date_nanos

  5. 布尔型:boolean

    true/false

  6. 二进制:binary

  7. 范围数据类型range: integer_range,、float_range、 long_range、double_range,、date_range、ip_range

    例子:

    // 添加映射create
    {
        "mappings": {
            "department": {
                "properties": {
                    "expected_number": {  // 预期员工数
                        "type": "integer_range"
                    },
                    "time_frame": {       // 发展时间线
                        "type": "date_range", 
                        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
                    },
                    "ip_whitelist": {     // ip白名单
                        "type": "ip_range"
                    }
                }
            }
        }
    }
    
    // 添加数据index
    {
        "expected_number" : {
            "gte" : 10,
            "lte" : 20
        },
        "time_frame" : { 
            "gte" : "2018-10-01 12:00:00", 
            "lte" : "2018-11-01"
        }, 
        "ip_whitelist": "192.168.0.0/16"
    }
    
    // 查询数据search
    {
        "query": {
            "term": {
                "expected_number": {
                    "value": 12
                }
            }
        }
    }
    
    {
        "query": {
            "range": {
                "time_frame": {
                    "gte": "208-08-01",
                    "lte": "2018-12-01",
                    "relation": "within" 
                }
            }
        }
    }
    

复杂的数据类型

  1. 对象类型:object

    JSON文档是分层的: 文档可以包含内部对象, 内部对象也可以包含内部对象。例如:

    // json
    {
        "name": "ma_shoufeng",
        "address": {
            "region": "China",
            "location": {"province": "GuangDong", "city": "GuangZhou"}
        }
    }
    
    // es存储方式
    {
        "name":                       "ma_shoufeng",
        "address.region":             "China",
        "address.location.province":  "GuangDong", 
        "address.location.city":      "GuangZhou"
    }
    
    // 此文档的映射mappings方式如下:
    {
        "mappings": {
            "developer": {
                "properties": {
                    "name": {"type": "text", "index": "true"},
                    "aggress": {
                        "properties": {
                            "region": {"type": "keyword", "index":"true"},
                            "location": {
                                "properties": {
                                    "province": {"type": "keyword", "index": "true"},
                                    "city": {"type": "keyword", "index": "true"}
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
  2. 嵌套类型:nested

    嵌套类型是对象数据类型的一个特例, 可以让array类型的对象被独立索引和搜索.

    // array类型,数据结构
    {
        "group": "stark",
        "performer": [
            {"first": "John", "last": "Snow"},
            {"first": "Sansa", "last": "Stark"}
        ]
    }
    
    // 内部存储结构
    {
        "group":              "stark",
        "performer.first": [ "john", "sansa" ],
        "performer.last":  [ "snow", "stark" ]
    }
    

    可以看出, user.first和user.last会被平铺为多值字段, 这样一来, John和Snow之间的关联性就丢失了。在查询时, 可能出现John Stark的结果。

    用nested类型解决object类型的不足
    如果需要对以最对象进行索引, 且保留数组中每个对象的独立性, 就应该使用嵌套数据类型.
    —— 嵌套对象实质是将每个对象分离出来, 作为隐藏文档进行索引.

    // 创建映射create
    PUT game_of_thrones
    {
        "mappings": {
            "role": {
                "properties": {
                    "performer": {"type": "nested"}
                }
            }
        }
    }
    
    // 添加数据index
    PUT game_of_thrones/role/1
    {
        "group" : "stark",
        "performer" : [
            {"first": "John", "last": "Snow"},
            {"first": "Sansa", "last": "Stark"}
        ]
    }
    
    // 搜索数据search
    {
        "query": {
            "nested": {
                "path": "performer",
                "query": {
                    "bool": {
                        "must": [
                            {"match": {"performer.first": "John"}},
                            {"match": {"performer.last": "Snow"}}
                        ]
                    }
                },
                "inner_hits": {
                    "highlight": {
                        "fields": {"performer.first": {}}
                    }
                }
            }
        }
    }
    
    
  3. 地理数据类型

    1. Geo-point: 地理点类型,地理点类型用于存储地理位置的经纬度对, 可用于:

      • 查找一定范围内的地理点;
      • 通过地理位置或相对某个中心点的距离聚合文档;
      • 将距离整合到文档的相关性评分中;
      • 通过距离对文档进行排序.
      // 添加映射
      {
          "mappings": {
              "developer": {
                  "properties": {
                      "location": {"type": "geo_point"}
                  }
              }
          }
      }
      
    2. Geo-shape: 地理形状类型

​

  1. 特殊数据类型

    1. IP: ip (IPv4 和 IPv6 地址)
    2. Completion:completion (to provide auto-complete suggestions)
    3. Token count:token_count (to count the number of tokens in a string)
    4. mapper-murmur3:murmur3(to compute hashes of values at index-time and store them in the index)
    5. mapper-annotated-text:annotated-text (to index text containing special markup (typically used for identifying named entities))
    6. Percolator:(Accepts queries from the query-dsl)
    7. Join:(Defines parent/child relation for documents within the same index)
    8. Alias:(Defines an alias to an existing field.)
    9. Rank feature:(Record numeric feature to boost hits at query time.)
    10. Rank features:(Record numeric features to boost hits at query time.)
    11. Dense vector:(Record dense vectors of float values.)
    12. Sparse vector:(Record sparse vectors of float values.)
    13. Search-as-you-type:(A text-like field optimized for queries to implement as-you-type completion)
  2. 数组类型

    在Elasticsearch中,数组不需要一个特定的数据类型,任何字段都默认可以包含一个或多个值,当然,这多个值都必须是字段指定的数据类型。

  3. Multi-fields

    Multi-fields 通常用来以不同的方式或目的索引同一个字段。比如,一个字符串类型字段可以同时被映射为 text 类型以用于全文检索、 keyword字段用于排序或聚合。又或者,你可以用standard分析器、english分析器和french分析器来索引同一个 text字段。

1.4 数据类型总结

数字类型

类型描述
byte有符号的8位整数,范围:[-128~127]
short有符号的16位整数,范围:[-32768 ~ 32767]
integer有符号的32位整数,范围:[ − 2 31 -2^{31} −231 ~ 2 31 2^{31} 231-1]
long有符号的64位整数,范围:[ − 2 63 -2^{63} −263 ~ 2 63 2^{63} 263-1]
float32位单精度浮点数
double64位双精度浮点数
half_float16位半精度IEEE754浮点类型
scaled_float缩放类型的的浮点数,比如price:字段只需精确到分,57.34缩放因子为100,存储结果为5734

文本类型

类型描述
text会被分词处理。如果进行聚合、排序计算需要开启fielddata进行内存预加载,不建议此使用方法。
keyword精准值,不会被分词。进行过滤、排序、聚合等操作时, 就应该使用keyword类型。

范围类型

类型描述
integer_range整数范围
long_range长整数范围
float_range浮点数范围
double_range长浮点数范围
date_range日期范围
ip_rangeip地址范围

其他类型

类型描述
date日期类型,可以设置日期的格式
date_nanos日期纳秒类型
boolean布尔类型
binary二进制

复杂类型

类型描述
objectjson对象嵌套类型。文档可以包含内部对象, 内部对象也可以包含内部对象
nested嵌套类型是对象数据类型的一个特例, 可以让array类型的对象被独立索引和搜索.
数组数组不需要一个特定的数据类型,任何字段都默认可以包含一个或多个值,当然,这多个值都必须是字段指定的数据类型。
geo-point地理点类型,地理点类型用于存储地理位置的经纬度。
geo-shape地理形状类型
multi-fieldsMulti-fields 通常用来以不同的方式或目的索引同一个字段。比如,一个字符串类型字段可以同时被映射为 text 类型以用于全文检索、 keyword字段用于排序或聚合。

特殊类型

类型描述
ipip (IPv4 和 IPv6 地址)
completionto provide auto-complete suggestions
token_countto count the number of tokens in a string
murmur3to compute hashes of values at index-time and store them in the index
annotated-textto index text containing special markup (typically used for identifying named entities)
percolatorAccepts queries from the query-dsl
joinDefines parent/child relation for documents within the same index
aliasDefines an alias to an existing field
rank featureRecord numeric feature to boost hits at query time.
rank featuresRecord numeric features to boost hits at query time
dense vectorRecord dense vectors of float values
sparse vectorRecord sparse vectors of float values.
search-as-you-typeA text-like field optimized for queries to implement as-you-type completion

二、Elasticsearch 基础操作

使用REST API可以对进行Elasticsearch 操作,详细的操作,查看官方文档:Elasticsearch 官方文档

接下来,使用Elasticsearch python客户端对es 操作。

首先安装Elasticsearch python库

pip install elasticsearch-dsl elasticsearch 

elasticsearch-dsl是对elasticsearch库进一步封装,也添加了elasticsearch中没有的复杂数据类型。

这两个库的官方文档如下:

elasticsearch 官方文档

elasticsearch 官方文档2

elasticsearch-dsl 官方文档

首先启动一个elasticsearch环境:

from elasticsearch import Elasticsearch, helpers
from elasticsearch_dsl import Search, Q

hosts = 'http://localhost:9200'
es = Elasticsearch(hosts=hosts)
s = Search(using=es)

# elasticsearch的启动信息
es.info()
2.1 对index操作

elasticsearch库中,对index进行操作,都是在es.indices.下面的方法中进行操作的。

下面是简单的对index增加、删除和判断是否存在的操作:

# 判断index是否存在
es.indices.exists(index='world')

# 创建index
es.indices.create(index='blog')

# 删除index
es.indices.delete(index='blog')

有时我们需要设置数据结构和类型,来创建index,需要设置mappings:

# 设置创建数据的结构和类型,以及index的参数
body = {
    "mappings": {
        "properties": {
            "group": {"type": "text"},
            "performer": {"type": "nested"}  # 嵌套数据类型
        }
    }
}
es.indices.create(index="demo3", **body)

有时我们需要根据模板创建index,首先创建一个模板es.indices.put_template,mappings中是数据的结构和类型:

# 创建模板
body = {
    "mappings": {
        "properties": {
            "@timestamp": {
                "type": "date"
            }
        }
    },
    "settings": {  # 设置
        "number_of_shards": 1 # 分片数量
    },
    "index_patterns": ["te*", "bar*"],
    # "priority": 500, # 优先级
    "version": 0,  # 版本号

}
es.indices.put_template(name='template_1', **body)

# 判断模板是否存在
es.indices.exists_template(name='template_1')

# 根据模板创建索引
es.indices.create(index='test1')
2.2 对document操作

对文档数据进行操作,在es.下面进行操作:

# 插入数据,一般只需要设置id和document就可以了
# 若没有index,则会动态创建一个index,并插入数据
dody = {
    "id": 0,
    "document": {
        "name": "wangwu",
        "age":20
    }
}
es.index(index='world', **dody)

# 更新数据,
# id是需要更新的文档id;doc是需要更新的数据。
body = {
    "id": 0,
    "doc": {
        "age": 25
    }
}
es.update(index='world', **body)

# 删除数据,删除对应id的文档
es.delete(index='world',id=5)

查询数据:

# get是获取一条文档
es.get(index='world',id='3')


# search是根据查询语句,对index进行查询
# index可省略,这样是在全局进行搜索。
body = {
    "query": {
        "match_all": {}
    }
}
es.search(index='world', **body)

搜索语句的语法在下面详细说明。

三、Elasticsearch 查询 DSL

Elasticsearch 查询 DSL大致关键字,首先浏览一下:

query:      查询语句
    match   匹配,可进行模糊匹配
    match_phrase    完全匹配
    match_all   全部输出
    term    完全匹配
    terms   一个字段,多值完全匹配
    multi_match     多字段,一个值匹配
        query
        fields
    prefix  前缀
    wildcard  模糊匹配 ?代表一个字符,*代表0个或多个字符
    regexp      正则匹配
    bool    条件查询
        must    全都满足,相当于and,计入得分
        filter  全都满足,相当于and,不计入得分
        must_not    全都不满足
        should      有一个满足,相当于or
    exists      字段存在
    range   范围查询
        field   具体字段
            gte     大于等于
            lt      小于

sort    排序语句
    field   具体字段
        order: desc/asc   升降序

aggs    聚合字段
    num

size    limit,限制输出的量
scroll  滚动输出,设置滚动存在的时间
3.1 query 部分
  • match

match是模糊匹配,是对分词之后的结果(text类型)进行匹配。

body = {
    'query': {
        'match': {
            'message': 'hello' # 只要message中包括hello,就会返回数据
        }
    }
}
es.search(index='world', **body)['hits']['hits']
  • match_phrase

match_phrase是完全匹配, 对分词之前的文本进行匹配

body = {
    'query': {
        'match_phrase': {
            'message': 'hello' # message为hello的文档,才会返回
        }
    }
}
es.search(index='world', **body)['hits']['hits']
  • match_all

match_all全部输出。

  • term

term 完全匹配,才会返回文档。

body = {
    'query': {
        'term': {
            'message': 'hello' # message为hello的文档,才会返回
        }
    }
}
es.search(index='world', **body)['hits']['hits']
  • terms

一个字段多值匹配的

body = {
    'query': {
        'terms': {
            'message': ['hello', 'world'] # message为 hello或world 的文档,才会返回
        }
    }
}
es.search(index='world', **body)['hits']['hits']
  • multi_match

multi_match: 多字段匹配某个值

body = {
    'query': {
        'multi_match': {
            'query': 'zhangsan',
            'fields': ['name', 'info']
        }
    }
}
es.search(index='world', **body)['hits']['hits']
  • prefix

prefix根据前缀进行模糊匹配

body = {
    'query': {
        'prefix': {
            'name': 'zhang'
        }
    }
}
es.search(index='world', **body)['hits']['hits']
  • wildcard

wildcard 模糊匹配,?代表一个字符,*代表0个或多个字符

body = {
    'query': {
        'wildcard': {
            'name': '?hang*'
        }
    }
}
es.search(index='world', **body)['hits']['hits']
  • regexp

regexp:根据正则表达式进行匹配。

body = {
    'query': {
        'regexp': {
            'name': '\w+'
        }
    }
}
es.search(index='world', **body)['hits']['hits']
  • bool

    bool :条件查询。其中有四种类型:must、filter、must_not、should

    • must :全部条件都需要满足,相当于and,返回结果计入得分。
    • filter:全部条件都需要满足,相当于and,返回结果不计入得分。
    • must_not:全都不满足
    • should:有一个满足就可以,相当于or
query = {
    'bool': {
        'must': [
            {'regexp': {'name': '\w+'}},
            {'term': {'age': 20}}
        ],
        'should': [
            {'regexp': {'name': 'wangwu'}},
            {'term': {'age': 24}}
        ],
        'must_not':[
            {'match': {'name': 'wangwu'}},
            {'term': {'age': 24}}
        ],
        'should': [
            {'match': {'name': 'lisi'}},
            {'terms': {'age': [20, 24]}}
        ]
    }
}
es.search(index='world',query=query)['hits']['hits']
  • exists

exists:查询有某个字段的文档

body = {
    'query': {
        'exists': {
            'field': 'name'
        }
    }
}
es.search(index='world', **body)
  • range

range 范围查询。gte:大于等于;lt: 小于

body = {
    'query': {
        'range': {
            'age': {
                'gte': 20,
                'lt': 30
            }
        }
    }
}
es.search(index='world', **body)

…其他查询

3.2 其他部分
3.2.1 排序字段

sort,可设置输出文档的顺序。

body = {
    'query': {
        'match_all': {}
    },
    'sort': {
        'age': {
            'order': 'desc' # 根据年龄降序排序
        }
    }
}
es.search(index='world', **body)
3.2.2 聚合字段
3.2.3 size和scroll

size,相当于limit,限制输出的条数。

scroll,滚动数据,当一个查询的结果有很多数据时,可以使用滚动查询。此参数是设置滚动查询存在的时间。

# 翻页查询 scroll
query = {
    'match_all': {}
}
size = 2

data = []

# 第一次查询
# 参数scroll的值是设置的 scroll 存活的时间,这里设置了2m,也就是2分钟
res = es.search(index='world', query=query, scroll='2m', size=size)
data.extend(res['hits']['hits'])

# 计算需要翻页查询的次数
total_num = res['hits']['total']['value']
times = total_num//size if total_num%size == 0 else total_num//size+1

# 滚动查询
for _ in range(times-1):
    res = es.scroll(scroll_id = res['_scroll_id'], scroll='1m')
    data.extend(res['hits']['hits'])

四、批量操作数据

4.1 批量插入/更新/删除数据

使用helpers.bulk(es, action)可以批量处理数据。

其中action是一个包含操作的迭代器,尽量使用生成器, 这样大批量的数据就不用加载到内存中了。

actions, 中迭代的对象,尽量与search()返回值相同,类似如下:

{
  '_index': 'index-name',
  '_id': 42,
  '_routing': 5,
  'pipeline': 'my-ingest-pipeline',
  '_source': {
    "title": "Hello World!",
    "body": "..."
  }
}

如果_source不存在,它会从文档中弹出所有元数据字段,并将其余部分用作文档数据:

{
  "_id": 42,
  "_routing": 5,
  "title": "Hello World!",
  "body": "..."
}

除了默认的添加文档,可以设置_op_type值,为index/delete/update,用于删除或更新值,如下:

# 添加
{
  '_op_type': 'index',
  '_index': 'index-name',
  '_id': 42,
  '_source': {'question': 'The life, universe and everything.'}
}

# 更新
{
  '_op_type': 'update',
  '_index': 'index-name',
  '_id': 42,
  '_source': {'question': 'The life.'}
}

# 删除
{
  '_op_type': 'delete',
  '_index': 'index-name',
  '_id': 42,
}
4.2 更新插入数据upsert

在一个kafka同步es的项目中,有两个topic需要消费,且需要把这个两个数据合并,于是就有了下面的需求:

  • 当数据不存在时,插入数据。
  • 当数据存在时,更新数据。

对于每条数据都进行判断的话,效率太低,于是就有了upsert这个方法。

方法一:

具体参考:

{
    "_op_type": '',
    '_index': '',
    '_id': 1,
    '_source': {
        'upsert': data,
        'script': {
            'source': script,
            'params': data
        }
    }
}

执行的逻辑是:

  • 若id不存在,则直接插入upsert的数据。
  • 若id存在,则执行script脚本。

所以把script脚本写成更新脚本,就可以起到更新数据的效果。

具体实现:

data = {
    'id': 0,
    'name': 'zhang'
}

# 创建更新脚本
script = ''
for k in data.keys():
    script += 'ctx._source.{0}=params.{0};'.format(k)

action = [{
    '_op_type': 'update',
    '_index': 'test',
    '_id': data['id'],
    '_source': {
        'upsert': data,
        'script': {
            'source': script,
            'params': data
        }
    }
}]

helpers.bulk(es, action)

方法二(简单):

具体参考:elasticsearch中批量的upsert

可以设置参数"doc_as_upsert" : true

具体实现:

data = {
    'id': 0,
    'name': 'zhang'
}

action = [{
    '_op_type': 'update',
    '_index': 'world',
    '_id': data['id'],
    'doc_as_upsert' : True,
    'doc': data
}]

helpers.bulk(es, action)

五、文本分析

基本定义内容:[text analyze](./text analyze.md)

默认情况下,Elasticsearch 使用standard分析器进行所有文本分析。该standard分析器为您提供对大多数自然语言和用例的开箱即用支持。如果您选择按原样使用standard 分析器,则无需进一步配置。

如果标准分析器不符合您的需求,请查看并测试 Elasticsearch 的其他内置分析器。内置分析器不需要配置,但有一些支持选项可用于调整其行为。例如,您可以使用standard要删除的自定义停用词列表配置分析器。

如果没有适合您需求的内置分析器,您可以测试并创建自定义分析器。自定义分析器涉及选择和组合不同的 分析器组件,让您更好地控制过程。

5.1 测试分析器

analyzeAPI是查看分析器生成术语的工具。可以在请求中内联指定内置分析器:

POST _analyze
{
  "analyzer": "whitespace",
  "text":     "The quick brown fox."
}

在python API中使用:

body = {
    'analyzer': 'whitespace',
    'text': "The quick brown fox."
}
es.indices.analyze(body=body)

它将返回:

{
  "tokens": [
    {
      "token": "The",
      "start_offset": 0,
      "end_offset": 3,
      "type": "word",
      "position": 0
    },
    {
      "token": "quick",
      "start_offset": 4,
      "end_offset": 9,
      "type": "word",
      "position": 1
    },
    {
      "token": "brown",
      "start_offset": 10,
      "end_offset": 15,
      "type": "word",
      "position": 2
    },
    {
      "token": "fox.",
      "start_offset": 16,
      "end_offset": 20,
      "type": "word",
      "position": 3
    }
  ]
}

其中包括分词的结果,开始分词的偏移量,结束分词的偏移量,类型和分词流的位置。

一个分析器包括:

  • 零个或多个字符过滤器char_filter

  • 一个分词器tokenizer

  • 零个或多个令牌过滤器filter

比如使用自定义的分析器:

POST _analyze
{
  "tokenizer": "standard",
  "filter":  [ "lowercase", "asciifolding" ],
  "text":      "Is this déja vu?"
}

python API

body = {
  "tokenizer": "standard",
  "filter":  [ "lowercase", "asciifolding" ],
  "text":      "Is this déja vu?"
}
es.indices.analyze(body=body)

它将返回:

{
  "tokens": [
    {
      "token": "is",
      "start_offset": 0,
      "end_offset": 2,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "this",
      "start_offset": 3,
      "end_offset": 7,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "deja",
      "start_offset": 8,
      "end_offset": 12,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "vu",
      "start_offset": 13,
      "end_offset": 15,
      "type": "<ALPHANUM>",
      "position": 3
    }
  ]
}

位置和字符偏移

从analyzeAPI 的输出可以看出,Analyzer 不仅将词转换为词,还记录每个词的顺序或相对位置(用于短语查询或词邻近查询),以及每个词的开始和结束字符偏移量。

当然也可以在特定索引上运行analyze,API可以参考custom分析器:

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "std_folded": { 
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_text": {
        "type": "text",
        "analyzer": "std_folded" 
      }
    }
  }
}

GET my-index-000001/_analyze 
{
  "analyzer": "std_folded", 
  "text":     "Is this déjà vu?"
}

GET my-index-000001/_analyze 
{
  "field": "my_text", 
  "text":  "Is this déjà vu?"
}

python API

body = {
  "settings": {
    "analysis": {
      "analyzer": {
        "std_folded": { 
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_text": {
        "type": "text",
        "analyzer": "std_folded" 
      }
    }
  }
}
# 创建index
es.indices.create(index='my-index-000001', **body)


# 可以指定分析器,或者指定某个text字段(使用它的分析器)
body = {
  "analyzer": "std_folded", 
  "text":     "Is this déjà vu?"
}
body = {
  "field": "my_text", 
  "text":  "Is this déjà vu?"
}
# 使用index中的分析器
es.indices.analyze(index='my-index-000001', body=body)

输出结果和上面单独使用analyze一样。

5.2 内置的分析器

内置分析器无需任何配置即可直接使用。但是,其中一些支持配置选项以改变其行为。例如,可以将standard分析器配置为支持停用词列表:

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "std_english": { 
          "type":      "standard",
          "stopwords": "_english_"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_text": {
        "type":     "text",
        "analyzer": "standard", 
        "fields": {
          "english": {
            "type":     "text",
            "analyzer": "std_english" 
          }
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "field": "my_text", 
  "text": "The old brown cow"
}

POST my-index-000001/_analyze
{
  "field": "my_text.english", 
  "text": "The old brown cow"
}

python API:

body = {
  "settings": {
    "analysis": {
      "analyzer": {
        "std_english": { 
          "type":      "standard",
          "stopwords": "_english_"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_text": {
        "type":     "text",
        "analyzer": "standard", 
        "fields": {
          "english": {
            "type":     "text",
            "analyzer": "std_english" 
          }
        }
      }
    }
  }
}
es.indices.create(index='my-index-000001', **body)


body = {
    'field': 'my_text',
    'text': 'The old brown cow'
}
# and
body = {
    'field': 'my_text.english',
    'text': 'The old brown cow'
}
es.indices.analyze(index='my-index-000001', body=body)

我们将std_english分析器定义为基于standard 分析器,但配置为删除预定义的英语停用词列表。

该my_text字段standard直接使用分析仪,无需任何配置。不会从此字段中删除停用词。 分词的结果是:[ the, old, brown, cow ]

该my_text.english字段使用std_english分析器,因此将删除英文停用词。分词的结果是: [ old, brown, cow ]

5.3 自定义分析器

当内置分析器不能满足您的需求时,您可以创建一个 custom,它需要满足:

5.3.1 配置

custom分析器接受以下参数:

配置说明
type分析仪类型。接受内置分析器类型。对于自定义分析器,使用custom或省略此参数。
tokenizer内置或定制的分词器。(必需的)
char_filter可选的内置或自定义 字符过滤器数组。
filter可选的内置或自定义 令牌过滤器数组。
position_increment_gap当索引一个文本值数组时,Elasticsearch 在一个值的最后一个词和下一个值的第一个词之间插入一个假的“间隙”,以确保一个短语查询不匹配来自不同数组元素的两个词。默认为100. 查看position_increment_gap更多
5.3.2 自定义分析器示例

示例一

这是一个结合了以下内容的示例:

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer": {
          "type": "custom", 
          "tokenizer": "standard",
          "char_filter": [
            "html_strip"
          ],
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_custom_analyzer",
  "text": "Is this <b>déjà vu</b>?"
}

python API

body = {
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer": {
          "type": "custom", 
          "tokenizer": "standard",
          "char_filter": [
            "html_strip"
          ],
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
  }
}
es.indices.put_settings(index='my-index-000001', body=body)
# 使用上面的put_settings时,需要先关闭index ,使用时再打开index
# es.indices.close(index='')
# es.indices.open(index='')

body = {
  "analyzer": "my_custom_analyzer",
  "text": "Is this <b>déjà vu</b>?"
}
es.indices.analyze(index='my-index-000001', body=body)

返回的结果是:

[ is, this, deja, vu ]

关闭索引,可以修改index的分析器和相关性参数

python api使用put_settings和put_mappings

前面的示例使用了标记器、标记过滤器和字符过滤器及其默认配置,但可以创建每个配置的版本并在自定义分析器中使用它们。

示例二

这是一个更复杂的示例,它结合了以下内容:

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer": { 
          "char_filter": [
            "emoticons"
          ],
          "tokenizer": "punctuation",
          "filter": [
            "lowercase",
            "english_stop"
          ]
        }
      },
      "tokenizer": {
        "punctuation": { 
          "type": "pattern",
          "pattern": "[ .,!?]"
        }
      },
      "char_filter": {
        "emoticons": { 
          "type": "mapping",
          "mappings": [
            ":) => _happy_",
            ":( => _sad_"
          ]
        }
      },
      "filter": {
        "english_stop": { 
          "type": "stop",
          "stopwords": "_english_"
        }
      }
    }
  }
}

POST my-index-000001/_analyze
{
  "analyzer": "my_custom_analyzer",
  "text": "I'm a :) person, and you?"
}

python API:

body = {
    'settings': {
        'analysis': {
            'analyzer': {
                'my_custom_analyzer': {
                    'char_filter': ['emoticons'],
                    'tokenizer': 'punctuation',
                    'filter': ['lowercase', 'english_stop']
                }
            },
            'tokenizer': {
                'punctuation': {
                    'type': 'pattern',
                    'pattern': '[ .,!?]'
                }
            },
            'char_filter': {
                'emoticons': {
                    'type': 'mapping',
                    'mappings': [
                        ':) => _happy_',
                        ':( => _sad_'
                    ]
                }
            },
            'filter': {
                'english_stop': {
                    'type': 'stop',
                    'stopwords': '_english_'
                }
            }
        }
    }
}
es.indices.put_settings(index='my-index-000001', body=body)
# 记得先关闭index

body = {
    'analyzer': 'my_custom_analyzer',
    'text': "I'm a :) person, and you?"
}
es.indices.analyze(index='my-index-000001', body=body)

为索引分配一个默认的自定义分析器,my_custom_analyzer. 此分析器使用稍后在请求中定义的自定义标记器、字符过滤器和标记过滤器。该分析器也省略了type参数。

它将返回:

[ i'm, _happy_, person, you ]
5.4 指定分析器的方式

Elasticsearch 提供了多种方法来指定内置或自定义分析器:

把事情简单化

在不同级别和不同时间指定分析仪的灵活性非常好……但仅在需要时。

在大多数情况下,一个简单的方法效果最好:为每个 text字段指定一个分析器,如为字段指定分析器中所述。

这种方法适用于 Elasticsearch 的默认行为,让您可以使用相同的分析器进行索引和搜索。它还可以让您使用get mapping API快速查看哪个分析器适用于哪个字段。

如果您通常不为索引创建映射,则可以使用 索引模板来实现类似的效果。

5.4.1 Elasticsearch 索引分析器

Elasticsearch 通过依次检查以下参数来确定要使用的索引分析器:

  1. 字段的analyzer映射参数。请参阅为字段指定分析器。
  2. analysis.analyzer.default索引设置 。请参阅为索引指定默认分析器。

如果没有指定这些参数, 则使用standard分析器。

5.4.1.1 指定字段的分析器

映射索引时,可以使用analyzer映射参数为每个text字段指定一个分析器。

以下创建索引 API请求将 whitespace分析器设置为title字段的分析器。

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "whitespace"
      }
    }
  }
}

5.4.1.2 指定索引的默认分析器

除了字段级分析器之外,您还可以设置备用分析器以使用该analysis.analyzer.default设置。

以下创建索引 API请求将 simple分析器设置为my-index-000001.

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "type": "simple"
        }
      }
    }
  }
}
5.4.2 Elasticsearch 搜索分析器

在大多数情况下,不需要指定不同的搜索分析器。这样做可能会对相关性产生负面影响并导致意外的搜索结果。

如果您选择指定单独的搜索分析器,我们建议您在部署到生产环境之前彻底测试您的分析配置。

在搜索时,Elasticsearch 通过依次检查以下参数来确定要使用的分析器:

  1. 搜索查询中的analyzer参数。请参阅为查询指定搜索分析器。
  2. 字段的search_analyzer映射参数。请参阅为字段指定搜索分析器。
  3. analysis.analyzer.default_search索引设置 。请参阅为索引指定默认搜索分析器。
  4. 字段的analyzer映射参数。请参阅为字段指定分析器。

如果没有指定这些参数, 则使用standard分析器。

5.4.2.1 指定查询的搜索分析器

编写全文查询时,可以使用analyzer 参数指定搜索分析器。如果提供,它将覆盖任何其他搜索分析器。

以下搜索 API请求将stop分析器设置为match查询的搜索分析器。

GET my-index-000001/_search
{
  "query": {
    "match": {
      "message": {
        "query": "Quick foxes",
        "analyzer": "stop"
      }
    }
  }
}

python API

body = {
    'query': {
        'match': {
            'message': {
                'query': 'Quick foxes',
                'analyzer': 'stop'
            }
        }
    }
}
es.search(index='my-index-000001', **body)

5.4.2.2 指定字段的搜索分析器

映射索引时,您可以使用search_analyzer映射参数为每个text字段指定搜索分析器。

如果提供了搜索分析器,则还必须使用analyzer参数指定索引分析器。

以下创建索引 API请求将 simple分析器设置为title字段的搜索分析器。

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "whitespace",
        "search_analyzer": "simple"
      }
    }
  }
}

5.4.2.3 指定索引的默认搜索分析器

创建索引时,您可以使用该设置设置默认搜索分析器analysis.analyzer.default_search。

如果提供了搜索分析器,则还必须使用该analysis.analyzer.default设置指定默认索引分析器。

以下 创建索引 API请求将 whitespace分析器设置为my-index-000001索引的默认搜索分析器。

PUT my-index-000001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "type": "simple"
        },
        "default_search": {
          "type": "whitespace"
        }
      }
    }
  }
}

六、别名alias

别名是一组数据流或索引的辅助名称。大多数 Elasticsearch API 接受别名来代替数据流或索引名称。

您可以随时更改别名的数据流或索引。如果您在应用程序的 Elasticsearch 请求中使用别名,则可以在不停机或更改应用程序代码的情况下重新索引数据。

6.1 别名类型

有两种类型的别名:

  • 数据流别名指向一个或多个数据流 。
  • 索引别名指向一个或多个索引 。

别名不能同时指向数据流和索引。也不能将数据流的支持索引添加到索引别名。

6.2 添加别名

要将现有数据流或索引添加到别名,请使用 aliases API的add操作。如果别名不存在,则请求创建它.

POST _aliases
{
  "actions": [
    {
      "add": {
        "index": "logs-nginx.access-prod",
        "alias": "logs"
      }
    }
  ]
}

python api

es.indices.put_alias(index='world', name='world-test1')

API的index和indices参数支持通配符(*)。同时匹配数据流和索引的通配符模式将返回错误。

POST _aliases
{
  "actions": [
    {
      "add": {
        "index": "logs-*",
        "alias": "logs"
      }
    }
  ]
}

python api

es.indices.put_alias(index='wor*', name='world-test1')
6.3 删除别名

要删除别名,使用 aliases API 的remove操作。

POST _aliases
{
  "actions": [
    {
      "remove": {
        "index": "logs-nginx.access-prod",
        "alias": "logs"
      }
    }
  ]
}

python api

es.indices.delete_alias(index='world', name='world-test1')
6.4 别名多个操作

可以使用aliases API 在单个原子操作中执行多个操作。

例如,logs别名指向单个数据流。以下请求将流交换为别名。在此交换期间,logs别名没有停机时间,并且永远不会同时指向两个流。

POST _aliases
{
  "actions": [
    {
      "remove": {
        "index": "logs-nginx.access-prod",
        "alias": "logs"
      }
    },
    {
      "add": {
        "index": "logs-my_app-default",
        "alias": "logs"
      }
    }
  ]
}
6.5 其他操作

具体详见:官方别名操作

引用:

3.elasticsearch数据类型总结

“whitespace”
}
}
}
}
}






### 六、别名alias

别名是一组数据流或索引的辅助名称。大多数 Elasticsearch API 接受别名来代替数据流或索引名称。

您可以随时更改别名的数据流或索引。如果您在应用程序的 Elasticsearch 请求中使用别名,则可以在不停机或更改应用程序代码的情况下重新索引数据。



#### 6.1 别名类型

有两种类型的别名:

- **数据流别名**指向一个或多个数据流 。
- **索引别名**指向一个或多个索引 。

别名不能同时指向数据流和索引。也不能将数据流的支持索引添加到索引别名。



#### 6.2 添加别名

要将现有数据流或索引添加到别名,请使用 [aliases API](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html)的`add`操作。如果别名不存在,则请求创建它.

```json
POST _aliases
{
  "actions": [
    {
      "add": {
        "index": "logs-nginx.access-prod",
        "alias": "logs"
      }
    }
  ]
}

python api

es.indices.put_alias(index='world', name='world-test1')

API的index和indices参数支持通配符(*)。同时匹配数据流和索引的通配符模式将返回错误。

POST _aliases
{
  "actions": [
    {
      "add": {
        "index": "logs-*",
        "alias": "logs"
      }
    }
  ]
}

python api

es.indices.put_alias(index='wor*', name='world-test1')
6.3 删除别名

要删除别名,使用 aliases API 的remove操作。

POST _aliases
{
  "actions": [
    {
      "remove": {
        "index": "logs-nginx.access-prod",
        "alias": "logs"
      }
    }
  ]
}

python api

es.indices.delete_alias(index='world', name='world-test1')
6.4 别名多个操作

可以使用aliases API 在单个原子操作中执行多个操作。

例如,logs别名指向单个数据流。以下请求将流交换为别名。在此交换期间,logs别名没有停机时间,并且永远不会同时指向两个流。

POST _aliases
{
  "actions": [
    {
      "remove": {
        "index": "logs-nginx.access-prod",
        "alias": "logs"
      }
    },
    {
      "add": {
        "index": "logs-my_app-default",
        "alias": "logs"
      }
    }
  ]
}
6.5 其他操作

具体详见:官方别名操作

引用:

3.elasticsearch数据类型总结

Python 玩转 Elasticsearch的一些技巧与经验 在Python项目中,我们可以选择以下几个库与Elasticsearch交互:elasticsearch-py:官方提供的低级客户端(Official low-level client for Elasticsearch),直接且灵活。elasticsearch-dsl:基于的高级封装,简化了很多操作,更适合日常使用。django-elasticsearch-dsl:为 Django 用户设计,基于elasticsearch-dsl,实现了与Django的深度集成。 阅读详情

相关推荐

【Python】Elasticsearch

要理解 Elasticsearch,我们不能仅仅将其看作一个数据库,它更是一个强大的、专为分布式环境设计的、开源的、实时的、用于搜索和分析的搜索引擎。它的诞生是为了解决传统数据库在处理非结构化数据、全文检索和大规模数据分析时遇到的瓶颈。Elasticsearch 的正式定义: Elasticsearch 是一个基于 Apache Lucene 构建的开源、分布式、RESTful 风格的搜索和分析引擎。它能够以极高的速度存储、搜索和分析大量数据。核心特性深度剖析:实时性 (Real-time):分布式 (Di

宅男很神经 1542

python操作ElasticSearch

利用python操作ElasticSearch 利用python对ElasticSearch进行操作主要会涉及两个python库elasticsearch和elasticsearch-dsl。除此之外,还会一个更为简单的python库:es-pandas。 其中,elasticsearch-py是一个官方提供的elasticsearch python客户端库,它只是对elasticsearch的rest API接口做了一层简单的封装。相对于这个客户端库,官方还提供了相对高级的elasticsearch-ds

weixin_42182448的博客 1万+

Elasticsearch 与 Python 整合:使用 Elasticsearch-py 进行开发

本指南系统解析 Elasticsearch 与 Python 的整合开发,覆盖从基础概念到高级实践的全生命周期。通过理论框架(分布式系统原理、倒排索引数学模型)、架构设计(客户端-集群交互模型)、实现机制(连接配置、DSL查询、批量API)、实际应用(日志分析、数据检索)及高级考量(安全、扩展、伦理)的分层阐述,为开发者提供从入门到专家的完整知识体系。核心包含生产级代码示例、可视化交互图及真实场景案例,助力高效构建 Elasticsearch 驱动的 Python 应用。高效交互。

2502_91592937的博客 1086

Elasticsearch:关于在 Python 中使用 Elasticsearch 你需要知道的一切 - 8.x

Elasticsearch 是一个非常强大的搜索引擎,使用非常广泛。本文的重点是使用 Python 批量创建 Elasticsearch 文档。我们仅仅触及了 Elasticsearch 搜索查询的皮毛。我有专门的文章介绍 Elasticsearch的 基本查询和高级查询,用于搜索和分析。Elasticsearch 原生语言中使用的查询与 Python 中使用的查询相同。因此,当你掌握了Kibana中的原生查询后,你就可以在Python中自由使用了。

Elastic 中国社区官方博客 9693

Python爬虫之Requests 库的介绍和操作实例!

一、什么是爬虫? 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。 其实通俗的讲就是通过程序去获取web页面上自己想要的数据,也就是自动抓取数据。 你可以爬去妹子的图片,爬取自己想看看的视频。。等等你想要爬取的数据,只要你能通过浏览器访问的数据都可以通过爬虫获取 二、爬虫的本质 模拟浏览器打开网页,获取网页中我们想要的那部分数据 浏览器打开网

爬遍所有网站 9817

Python入门实战:Python云计算编程基础

1.背景介绍 Python在近年来得到了越来越多人的青睐。Python编程语言不仅易于学习、运行速度快、代码简洁、可扩展性强、社区支持活跃等特点,还被广泛应用于科学计算、数据分析、机器人控制、网络爬虫、游戏开发等领域。因此,越来越多的人开始关注并选择Python作为自己的主要编程语言。虽然Python有很多种用途,但其中最常见的一种就是进行云计算编程。

AI天才研究院 431

笔记13:Python 和 Elasticsearch 构建简易搜索

Python 和 Elasticsearch 构建简易搜索 1 ES基本介绍 概念介绍 Elasticsearch是一个基于Lucene库的搜索引擎。它提供了一个分布式、支持多租户的全文搜索引擎,它可以快速地储存、搜索和分析海量数据。Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。Elasticsearch至少需要Java 8。Elastics...

weixin_30527143的博客 186

【Python爬虫(4)】揭开Python爬虫的神秘面纱:基础概念全解析

网络爬虫,又被称为网页蜘蛛、网络机器人 ,在 FOAF 社区中,也常被叫做网页追逐者。从定义上来说,它是一种按照一定规则,自动抓取互联网信息的程序或脚本。就如同它的名字 “爬虫” 一样,它就像是一只在网络世界中不知疲倦的蜘蛛,沿着网页中的链接,从一个页面爬行到另一个页面,获取并收集我们需要的各种信息。网络爬虫的工作过程高度自动化。一旦设定好规则和目标,它就能自动地在互联网这个巨大的信息海洋中穿梭。

邓邓子的博客 2720

Elasticsearch的介绍 以及使用python操作es详细步骤

一. 什么是 Elasticsearch 想查数据就免不了搜索,搜索就离不开搜索引擎,百度、谷歌都是一个非常庞大复杂的搜索引擎,他们几乎索引了互联网上开放的所有网页和数据。然而对于我们自己的业务数据来说,肯定就没必要用这么复杂的技术了,如果我们想实现自己的搜索引擎,方便存储和检索,Elasticsearch 就是不二选择,它是一个全文搜索引擎,可以快速地储存、搜索和分析海量数据。 Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful w

m0_55070913的博客 473

44、探索ElasticSearch:深入理解与实践

本文全面介绍了ElasticSearch的核心概念、架构原理及实际应用,涵盖节点与集群配置、分片与复制机制、索引和文档管理、搜索与聚合查询等基础内容。同时深入探讨了脚本编写、Rivers插件的使用以及自定义插件开发等高级功能,并提供了Java和Python语言的集成实践方法。适用于希望深入了解ElasticSearch并将其应用于大规模数据处理的技术人员。

g5h6i7j的博客 69

配置Dot1q终结子接口实现跨设备VLAN间通信示例

示例图 一.实验目的 1.配置Dot1q终结子接口实现跨设备VLAN间通信示例 二.注意事项 1.Dot1q终结子接口和QinQ终结子接口不支持透传不带VLAN Tag的报文, 收到不带VLAN Tag的报文会直接丢弃 2.由于三层以太网子接口不支持VLAN报文,当它收到VLAN报文时,会将VLAN报文当成是 非法报文而丢弃,因此,需要在子接口上将VLAN Tag剥掉,也就是需要VLAN终结 三.VLAN终结简介 1.VLAN终结的实质包含两个方面: ①.对接口接收到报文,剥除VLAN标

qq_44751470的博客 7097

《Python3 网络爬虫开发实战》:便于高效检索的 Elasticsearch 存储

Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库™ 基础之上。那 Lucene 又是什么呢?Lucene可能是目前存在的(不论开源还是私有的)拥有最先进、高性能和全功能搜索引擎功能的库,但也仅仅只是一个库。要想用 Lucene,我们需要编写Java 并引用 Lucene 包才可以,而且我们需要对信息检索有一定程度的理解。为了解决这个问题,Elasticsearch 就诞生了。

qq_34589842的博客 762

DIY压电陶瓷传感器信号放大:从拆解到JFET电路实战(附示波器实测数据)

本文详细介绍了如何利用废旧设备拆解的压电陶瓷片,结合JFET(结型场效应管)高输入阻抗特性,DIY搭建高灵敏度振动传感器放大电路。从元件拆解、参数实测到JFET共源极放大器实战搭建与调试,提供了完整的步骤、示波器实测数据及优化方案,帮助电子爱好者实现低功耗振动检测应用。

weixin_29195615的博客 386

Elasticsearch 基本介绍及其与 Python 的对接实现

么是 Elasticsearch 想查数据就免不了搜索,搜索就离不开搜索引擎,百度、谷歌都是一个非常庞大复杂的搜索引擎,他们几乎索引了互联网上开放的所有网页和数据。然而对于我们自己的业务数据来说,肯定就没必要用这么复杂的技术了,如果我们想实现自己的搜索引擎,方便存储和检索,Elasticsearch 就是不二选择,它是一个全文搜索引擎,可以快速地储存、搜索和分析海量数据。 为什么要用 E...

heima201907的博客 205

手把手教你用STM32F429+FreeRTOS搭建开源SIP电话(附代码与避坑指南)

本文详细介绍了如何使用STM32F429和FreeRTOS搭建开源SIP电话系统,涵盖硬件选型、FreeRTOS任务划分、PJSIP协议栈移植、音频系统优化及安全实践。通过实战案例和代码示例,帮助开发者快速实现嵌入式VoIP通信,特别适合物联网和音视频通信领域的应用开发。

weixin_33582311的博客 354

用Python+LLM实现小说自动转剧本:从爬取到生成的完整实战指南(附GitHub源码)

本文提供了一份完整的实战指南,详细介绍了如何利用Python和大语言模型(LLM)构建一个自动化的小说转剧本工具。文章从网络爬虫获取文本开始,逐步讲解了使用LLM进行智能解析与结构化、集成专业模型进行情绪分析与动作生成,最终合成并输出格式规范的剧本文档。通过模块化架构设计和附带的GitHub源码,帮助开发者掌握从数据获取到内容生成的全流程,实现高效的小说剧本转换器。

xray4的博客 409

[es7]elasticsearch安装、创建索引、插数据、检索操作

文章目录安装阶段elasticsearch7.9安装[单集群单节点、开启权限认证]创建索引阶段ElasticSearch入门的基础概念Elasticsearch入门交互操作[es7]在往elasticsearch插数据之前,mapping和setting要怎么配置呢?插数据阶段[es7]使用python向elasticsearch中插数据数据查询阶段[es7]es查询实践示例 安装阶段 elasticsearch7.9安装[单集群单节点、开启权限认证] 创建索引阶段 ElasticSearch入门的基础概念

SCUhzs 1783

实战复盘:如何用ATE(自动测试设备)搞定一颗MCU的功能测试全流程

本文详细解析了如何利用ATE(自动测试设备)完成MCU功能测试的全流程,涵盖测试需求分析、测试向量生成、ATE测试程序开发及调试实战。通过真实案例分享,帮助工程师高效解决芯片测试中的常见问题,提升Functional Test的准确性和效率。

weixin_30872157的博客 485

ElasticSearch的全文搜索与高亮显示: 提升搜索体验

1.背景介绍 ElasticSearch是一个开源的搜索和分析引擎,基于Lucene库,具有实时搜索、分布式搜索和高性能等特点。它可以用于实现全文搜索、文本分析、数据聚合等功能。在现代应用中,ElasticSearch被广泛应用于搜索引擎、知识管理系统、日志分析、实时数据处理等领域。 全文搜索是指在文档中搜索包含特定关键词的内容。高亮显示则是在搜索结果中以粗体或其他方式突出显示关键词,以便用户...

AI天才研究院 1796

西门子PLC新手必看:200SMART与1200/1500的MODBUS RTU通讯实战(附完整配置流程)

本文详细解析了西门子PLC中S7-200 SMART与S7-1200/1500之间实现MODBUS RTU通讯的完整实战流程。内容涵盖硬件接线、软件配置及程序编写,重点讲解了200SMART作为从站、1200/1500作为主站的典型架构,并提供了关键功能块的使用方法和常见问题排查技巧,帮助新手快速打通不同系列PLC间的数据交换。

weixin_29214559的博客 393

二维矩形件排样算法之最低水平线算法实现

最低水平线算法的简单实现(Python) 1、二维矩形排样算法众多,最早的有BL算法、下台阶算法、最低水平线算法等,其中最低水平线算法及其优化算法应用较多,是与智能优化算法(遗传算法、模拟退火算法等)结合的最多的算法,本文利用python对最低水平线算法做了实现...

峰爸的博客 1万+

Elasticsearch基础及python操作

类型是模拟mysql中数据库下面有N张表(Table)的概念,一个索引库下可以有不同类型的索引,比如商品索引,订单索引,其数据格式不同。在数据库中的增insert、删delete、改update、查select操作等价于ES中的增PUT、删Delete、改POST、查GET。:indices是index的复数,代表许多的索引,等价于关系型数据库中的数据库(DataBase):文档中的属性,相当于一个数据库表(Table)下的多列(column,属性)定义了表、每个表的字段,还有表和字段之间的关系。...

m0_55070913的博客 681

RK3588 hdmiout调试(一)

RK3588 hdmiout调试(一)

目前从事linux驱动开发,多交流多学习吧 5169

elasticsearch python连接池吗_在Python中使用Elasticsearch

原标题:在Python中使用Elasticsearch来源:Python程序员ID:pythonbuluo在这篇文章中,我将讨论Elasticsearch以及如何将其整合到不同的Python应用程序中。什么是ElasticSearch?ElasticSearch(ES)是一个建立在Apache Lucene之上的高度可用的分布式开源搜索引擎。它基于Java构建的,因此可用于许多平台。数据以JSON...

weixin_39664477的博客 1182

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

分布式搜索引擎:Elasticsearch 快速入门

文章目录一、Elasticsearch介绍1.1 介绍1.2 安装(Ubuntu 20.04)1.3 安装 Kinaba (官方客户端,可选)1.4 核心概念1.5 与 MySQL 对比二、反向索引原理三、ES 安装插件3.1 离线安装3.2 在线安装四、ES 操作4.1 索引操作4.2 映射操作4.2.1 字段类型4.2.2 映射参数4.2.3 映射操作4.3 文档操作4.4 文档查询4.4.1 全文查询4.4.2 词语级别查询4.4.3 布尔查询4.4.5 过滤查询4.5 排序4.6 分页4.7 高亮显

花城的博客 2080

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

上一篇: gRPC 框架 简单使用(python版)
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力生活的黄先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值