Golang操作ES全系列(olivere curl操作es)

news2024/12/24 8:42:42

Golang操作ES全系列(olivere & curl操作es)

🚀全部代码(欢迎👏🏻star):

  • https://github.com/ziyifast/ziyifast-code_instruction/tree/main/go-demo/go-es

1 olivere

创建client

package main

import (
	"crypto/tls"
	"fmt"
	"github.com/olivere/elastic/v7"
	"net"
	"net/http"
	"time"
)

var (
	//host = "http://localhost:9200"
	host = "http://es.xx.ziyi.com"
)

func main() {
	esClient, err := elastic.NewClient(
		elastic.SetURL(host),
		elastic.SetSniff(false),
		elastic.SetBasicAuth("", ""),
		elastic.SetHttpClient(&http.Client{Transport: &DecoratedTransport{
			tp: &http.Transport{
				Proxy: http.ProxyFromEnvironment,
				DialContext: (&net.Dialer{
					Timeout:   30 * time.Second,
					KeepAlive: 30 * time.Second,
				}).DialContext,
				ForceAttemptHTTP2:     true,
				MaxIdleConns:          100,
				IdleConnTimeout:       90 * time.Second,
				TLSHandshakeTimeout:   10 * time.Second,
				ExpectContinueTimeout: 1 * time.Second,
				TLSClientConfig: &tls.Config{
					InsecureSkipVerify: true,
				},
			},
		}}),
	)
	if err != nil {
		panic(err)
	}
	fmt.Println(esClient)
}

type DecoratedTransport struct {
	tp http.RoundTripper
}

func (d *DecoratedTransport) RoundTrip(request *http.Request) (*http.Response, error) {
	request.Host = "es.xx.ziyi.com"
	return d.tp.RoundTrip(request)
}

在这里插入图片描述

检测索引是否存在

func isExistIndex(esClient *elastic.Client) {
	isExist, err := esClient.IndexExists("test-ziyi-1-100004-100136").Do(context.TODO())
	if err != nil {
		panic(err)
	}
	if isExist {
		println("index exists")
	} else {
		println("index not exists")
	}
}

创建索引

func createIndex(esClient *elastic.Client) {
	type m map[string]interface{}
	indexMapping := m{
		"settings": m{
			"number_of_shards":   5, //分片数
			"number_of_replicas": 1, //副本数
		},
		"mappings": m{
			"properties": m{ //索引属性值
				"book_name": m{ //索引属性名
					"type": "text", //filed类型
					//"analyzer": "ik_max_word", //使用ik分词器进行分词
					"index": true,  //当前field可以被用于查询条件
					"store": false, //是否额外存储
				},
				"author": m{
					"type": "keyword", //作为关键字不分词
				},
				"word_count": m{
					"type": "long",
				},
				"on_sale_time": m{
					"type":   "date",
					"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis",
				},
				"book_desc": m{
					"type": "text",
					//"analyzer": "ik_max_word",
				},
			},
		},
	}
	result, err := esClient.CreateIndex("test-ziyi-1-100004-100136").BodyJson(indexMapping).Do(context.Background())
	if err != nil {
		panic(err)
	}
	if result.Acknowledged {
		println("create index success")
	} else {
		println("create index failed")
	}
}

删除索引

# 除了程序我们也可以先通过curl查看索引是否存在
curl http://localhost:9200/_cat/indices?v | grep ziyi

在这里插入图片描述

func deleteIndex(esClient *elastic.Client) {
	response, err := esClient.DeleteIndex("test-ziyi-1-100004-100136").Do(context.Background())
	if err != nil {
		panic(err)
	}
	println(response.Acknowledged)
}

添加记录doc

# _doc/1 # 表明查询id为1的doc文档
# test-ziyi-1-100004-100136指定索引名
curl -X GET "http://localhost:9200/test-ziyi-1-100004-100136/_doc/1?pretty"

在这里插入图片描述

func addDoc(esClient *elastic.Client) {
	type m map[string]interface{}
	documentMappings := m{
		"book_name":    "士兵突击",
		"author":       "兰晓龙",
		"word_count":   100000,
		"on_sale_time": "2000-01-05",
		"book_desc":    "一个关于部队的...",
	}
	//如果不指定id,则es会自动生成一个id(杂乱无序不好维护),response为返回的文档id
	//response, err := esClient.Index().Index("test-ziyi-1-100004-100136").BodyJson(documentMappings).Do(context.Background())
	response, err := esClient.Index().Index("test-ziyi-1-100004-100136").Id("1").BodyJson(documentMappings).Do(context.Background()) //指定id
	if err != nil {
		panic(err)
	}
	println(response.Id)
}

更新doc记录

在这里插入图片描述

func updateDoc(esClient *elastic.Client) {
	type m map[string]interface{}
	docMappings := m{
		"book_name":    "士兵突击",
		"author":       "袁朗",
		"word_count":   100000,
		"on_sale_time": "2000-01-05",
		"book_desc":    "一个关于部队的...",
	}
	//覆盖式修改(response返回doc记录的id)
	response, err := esClient.Update().Index("test-ziyi-1-100004-100136").Id("1").Doc(docMappings).Do(context.Background())
	//指定字段修改
	//response, err := esClient.Update().Index("test-ziyi-1-100004-100136").Id("1").Doc(map[string]interface{}{
	//	"book_name": "我的团长我的团",
	//}).Do(context.Background())
	if err != nil {
		panic(err)
	}
	println(response.Id)
}

删除doc记录

func deleteDoc(esClient *elastic.Client) {
	//response返回删除的doc Id,如果要删除的doc不存在,则直接返回err not found
	response, err := esClient.Delete().Index("test-ziyi-1-100004-100136").Id("1").Do(context.Background())
	if err != nil {
		panic(err)
	}
	println(response.Id)
}

批处理

func sendBulkRequest(esClient *elastic.Client) {
	bulkRequest := esClient.Bulk()
	for i := 0; i < 10; i++ {
		docMappings := map[string]interface{}{
			"book_name":    fmt.Sprintf("士兵突击-%d", i),
			"author":       "袁朗",
			"on_sale_time": "2000-01-05",
			"book_desc":    "一个关于部队的...",
		}
		bulkRequest = bulkRequest.Add(elastic.NewBulkIndexRequest().Index("test-ziyi-1-100004-100136").Doc(docMappings))
	}
	bulkResponse, err := bulkRequest.Do(context.Background())
	if err != nil {
		panic(err)
	}
	if bulkResponse.Errors {
		for _, item := range bulkResponse.Items {
			for _, action := range item {
				if action.Error != nil {
					fmt.Printf("Error for item: %s: %s", action.Error.Index, action.Error.Reason)
				}
			}
		}
	} else {
		fmt.Println("All bulk requests executed successfully")
	}
}

普通查询

func simpleSearch(esClient *elastic.Client) {
	response, err := esClient.Search([]string{"test-ziyi-1-100004-100136"}...).Query(elastic.NewTermQuery("author", "袁朗")).Size(100).Do(context.TODO())
	if err != nil {
		panic(err)
	}
	fmt.Println(response.Hits.Hits)
}

在这里插入图片描述

searchAfter翻页查询

func searchAfterSearch(esClient *elastic.Client) {
	var lastHit *elastic.SearchHit
	for {
		q := elastic.NewBoolQuery().
			Must(elastic.NewTermQuery("book_name", "士"))
		searchSource := elastic.NewSearchSource().Query(q).Size(2).Sort("_id", false)
		if lastHit != nil {
			fmt.Printf("search After %+v\n", lastHit.Sort)
			searchSource.SearchAfter(lastHit.Sort...)
		}
		dsl, err := searchSource.MarshalJSON()
		if err != nil {
			panic(err)
		}
		fmt.Printf("dsl %s\n", string(dsl))
		searchResult, err := esClient.Search().Index("test-ziyi-1-100004-100136").SearchSource(searchSource).Do(context.Background())
		if err != nil {
			panic(err)
		}
		if len(searchResult.Hits.Hits) == 0 {
			fmt.Println("no more data")
			break
		}
		for _, hit := range searchResult.Hits.Hits {
			res := make(map[string]interface{})
			if err = json.Unmarshal(hit.Source, &res); err != nil {
				panic(err)
			}
			fmt.Printf("search %s %s\n", hit.Id, res["author"])
		}
		lastHit = searchResult.Hits.Hits[len(searchResult.Hits.Hits)-1]
	}
}

全部代码

package main

import (
	"context"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"github.com/olivere/elastic/v7"
	"net"
	"net/http"
	"time"
)

var (
	host = "http://test.ziyi.com"
)

func main() {
	esClient := CreateEsClient()
	fmt.Println(esClient)
	//1. 操作索引
	//isExistIndex(esClient)
	//createIndex(esClient)
	//deleteIndex(esClient)

	//2. 操作doc文档(记录)
	//addDoc(esClient)
	//updateDoc(esClient)
	//deleteDoc(esClient)

	//3. 批处理请求
	//sendBulkRequest(esClient)

	//4. 查询
	//simpleSearch(esClient)
	//searchAfterSearch(esClient)

}

func searchAfterSearch(esClient *elastic.Client) {
	var lastHit *elastic.SearchHit
	for {
		q := elastic.NewBoolQuery().
			Must(elastic.NewTermQuery("book_name", "士"))
		searchSource := elastic.NewSearchSource().Query(q).Size(2).Sort("_id", false)
		if lastHit != nil {
			fmt.Printf("search After %+v\n", lastHit.Sort)
			searchSource.SearchAfter(lastHit.Sort...)
		}
		dsl, err := searchSource.MarshalJSON()
		if err != nil {
			panic(err)
		}
		fmt.Printf("dsl %s\n", string(dsl))
		searchResult, err := esClient.Search().Index("test-ziyi-1-100004-100136").SearchSource(searchSource).Do(context.Background())
		if err != nil {
			panic(err)
		}
		if len(searchResult.Hits.Hits) == 0 {
			fmt.Println("no more data")
			break
		}
		for _, hit := range searchResult.Hits.Hits {
			res := make(map[string]interface{})
			if err = json.Unmarshal(hit.Source, &res); err != nil {
				panic(err)
			}
			fmt.Printf("search %s %s\n", hit.Id, res["author"])
		}
		lastHit = searchResult.Hits.Hits[len(searchResult.Hits.Hits)-1]
	}
}

func simpleSearch(esClient *elastic.Client) {
	response, err := esClient.Search([]string{"test-ziyi-1-100004-100136"}...).Query(elastic.NewTermQuery("author", "袁朗")).Size(100).Do(context.TODO())
	if err != nil {
		panic(err)
	}
	fmt.Println(response.Hits.Hits)
}

func sendBulkRequest(esClient *elastic.Client) {
	bulkRequest := esClient.Bulk()
	for i := 0; i < 10; i++ {
		docMappings := map[string]interface{}{
			"book_name":    fmt.Sprintf("士兵突击-%d", i),
			"author":       "aa",
			"on_sale_time": "2000-01-05",
			"book_desc":    "一个关于部队的...",
		}
		bulkRequest = bulkRequest.Add(elastic.NewBulkIndexRequest().Index("test-ziyi-1-100004-100136").Doc(docMappings))
	}
	bulkResponse, err := bulkRequest.Do(context.Background())
	if err != nil {
		panic(err)
	}
	if bulkResponse.Errors {
		for _, item := range bulkResponse.Items {
			for _, action := range item {
				if action.Error != nil {
					fmt.Printf("Error for item: %s: %s", action.Error.Index, action.Error.Reason)
				}
			}
		}
	} else {
		fmt.Println("All bulk requests executed successfully")
	}
}

func deleteDoc(esClient *elastic.Client) {
	//response返回删除的doc Id,如果要删除的doc不存在,则直接返回err not found
	response, err := esClient.Delete().Index("test-ziyi-1-100004-100136").Id("1").Do(context.Background())
	if err != nil {
		panic(err)
	}
	println(response.Id)
}

func updateDoc(esClient *elastic.Client) {
	type m map[string]interface{}
	docMappings := m{
		"book_name":    "士兵突击",
		"author":       "袁朗",
		"word_count":   100000,
		"on_sale_time": "2000-01-05",
		"book_desc":    "一个关于部队的...",
	}
	//覆盖式修改(response返回doc记录的id)
	response, err := esClient.Update().Index("test-ziyi-1-100004-100136").Id("1").Doc(docMappings).Do(context.Background())
	//指定字段修改
	//response, err := esClient.Update().Index("test-ziyi-1-100004-100136").Id("1").Doc(map[string]interface{}{
	//	"book_name": "我的团长我的团",
	//}).Do(context.Background())
	if err != nil {
		panic(err)
	}
	println(response.Id)
}

func addDoc(esClient *elastic.Client) {
	type m map[string]interface{}
	documentMappings := m{
		"book_name":    "士兵突击",
		"author":       "兰晓龙",
		"word_count":   100000,
		"on_sale_time": "2000-01-05",
		"book_desc":    "一个关于部队的...",
	}
	//如果不指定id,则es会自动生成一个id(杂乱无序不好维护),response为返回的文档id
	//response, err := esClient.Index().Index("test-ziyi-1-100004-100136").BodyJson(documentMappings).Do(context.Background())
	response, err := esClient.Index().Index("test-ziyi-1-100004-100136").Id("1").BodyJson(documentMappings).Do(context.Background()) //指定id
	if err != nil {
		panic(err)
	}
	println(response.Id)
}

func deleteIndex(esClient *elastic.Client) {
	response, err := esClient.DeleteIndex("test-ziyi-1-100004-100136").Do(context.Background())
	if err != nil {
		panic(err)
	}
	println(response.Acknowledged)
}

func createIndex(esClient *elastic.Client) {
	type m map[string]interface{}
	indexMapping := m{
		"settings": m{
			"number_of_shards":   5, //分片数
			"number_of_replicas": 1, //副本数
		},
		"mappings": m{
			"properties": m{ //索引属性值
				"book_name": m{ //索引属性名
					"type": "text", //filed类型
					//"analyzer": "ik_max_word", //使用ik分词器进行分词
					"index": true,  //当前field可以被用于查询条件
					"store": false, //是否额外存储
				},
				"author": m{
					"type": "keyword", //作为关键字不分词
				},
				"word_count": m{
					"type": "long",
				},
				"on_sale_time": m{
					"type":   "date",
					"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis",
				},
				"book_desc": m{
					"type": "text",
					//"analyzer": "ik_max_word",
				},
			},
		},
	}
	result, err := esClient.CreateIndex("test-ziyi-1-100004-100136").BodyJson(indexMapping).Do(context.Background())
	if err != nil {
		panic(err)
	}
	if result.Acknowledged {
		println("create index success")
	} else {
		println("create index failed")
	}
}

func isExistIndex(esClient *elastic.Client) {
	isExist, err := esClient.IndexExists("test-ziyi-1-100004-100136").Do(context.TODO())
	if err != nil {
		panic(err)
	}
	if isExist {
		println("index exists")
	} else {
		println("index not exists")
	}
}

func CreateEsClient() *elastic.Client {
	esClient, err := elastic.NewClient(
		elastic.SetURL(host),
		elastic.SetSniff(false),
		elastic.SetBasicAuth("", ""),
		elastic.SetHttpClient(&http.Client{Transport: &DecoratedTransport{
			tp: &http.Transport{
				Proxy: http.ProxyFromEnvironment,
				DialContext: (&net.Dialer{
					Timeout:   30 * time.Second,
					KeepAlive: 30 * time.Second,
				}).DialContext,
				ForceAttemptHTTP2:     true,
				MaxIdleConns:          100,
				IdleConnTimeout:       90 * time.Second,
				TLSHandshakeTimeout:   10 * time.Second,
				ExpectContinueTimeout: 1 * time.Second,
				TLSClientConfig: &tls.Config{
					InsecureSkipVerify: true,
				},
			},
		}}),
	)
	if err != nil {
		panic(err)
	}
	return esClient
}

type DecoratedTransport struct {
	tp http.RoundTripper
}

func (d *DecoratedTransport) RoundTrip(request *http.Request) (*http.Response, error) {
	request.Host = "test.ziyi.com"
	return d.tp.RoundTrip(request)
}

2 go-elasticsearch

searchAfter翻页查询

package main

import (
	"context"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"github.com/cenkalti/backoff/v4"
	"github.com/elastic/go-elasticsearch/v7"
	"github.com/elastic/go-elasticsearch/v7/estransport"
	"net"
	"net/http"
	"os"
	"strings"
	"time"
)

var (
	url      = []string{"http://test.ziyi.com"}
	username = ""
	password = ""
	sort     = json.RawMessage(`[{"_id":{"order":"desc"}}]`)
	aggs     = json.RawMessage(`{"size": {"sum": {"field": "size"}},"count":{"value_count": {"field": "_id"}}}`)
	size     = 2
	indices  = []string{"test-ziyi-1-100004-100136"}
)

func main() {
	esClient, err := CreateClient(url, username, password)
	if err != nil {
		panic(err)
	}
	var searchAfter []interface{}

	for {
		dsl := Dsl{
			Sort:        sort,
			Size:        size,
			SearchAfter: searchAfter,
			Query: map[string]interface{}{
				"bool": map[string]interface{}{
					"must": map[string]interface{}{
						"wildcard": map[string]interface{}{
							"book_name": "士",
						},
						//"match_all": map[string]interface{}{},
					},
				},
			},
		}
		queryJson, err := json.MarshalIndent(dsl, "", "\t")
		if err != nil {
			panic(err)
		}
		fmt.Printf("queryJson:%s\n", queryJson)
		res, err := esClient.Search(
			esClient.Search.WithContext(context.Background()),
			esClient.Search.WithIndex(indices...),
			esClient.Search.WithBody(strings.NewReader(string(queryJson))),
			esClient.Search.WithTrackTotalHits(false),
		)
		if err != nil {
			panic(err)
		}
		var result struct {
			Hits struct {
				Hits []struct {
					Index  string                 `json:"_index"`
					ID     string                 `json:"_id"`
					Sort   []interface{}          `json:"sort"`
					Source map[string]interface{} `json:"_source"`
				} `json:"hits"`
			} `json:"hits"`
		}

		if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
			panic(err)
		}
		err = res.Body.Close()
		if err != nil {
			panic(err)
		}
		if len(result.Hits.Hits) > 0 {
			lastHit := result.Hits.Hits[len(result.Hits.Hits)-1]
			searchAfter = lastHit.Sort
		} else {
			break
		}
		for _, h := range result.Hits.Hits {
			fmt.Printf("=====id:%s book_name:%s\n", h.ID, h.Source["book_name"])
		}
	}
}

type Dsl struct {
	Sort        json.RawMessage        `json:"sort"`
	Size        int                    `json:"size"`
	SearchAfter []interface{}          `json:"search_after,omitempty"`
	Query       map[string]interface{} `json:"query"`
}

func CreateClient(url []string, username, password string) (*elasticsearch.Client, error) {
	es, err := elasticsearch.NewClient(genConfig(url, username, password))
	if err != nil {
		panic(err)
		return nil, err
	}
	res, err := es.Info()
	if err != nil {
		panic(err)
		return nil, err
	}
	defer res.Body.Close()
	return es, nil

}

type DecoratedTransport struct {
	tp http.RoundTripper
}

func (d *DecoratedTransport) RoundTrip(request *http.Request) (*http.Response, error) {
	request.Host = "test.ziyi.com"
	return d.tp.RoundTrip(request)
}

func genConfig(url []string, username, password string) elasticsearch.Config {
	retryBackoff := backoff.NewExponentialBackOff()
	cfg := elasticsearch.Config{
		Addresses:     url,
		Logger:        &estransport.ColorLogger{Output: os.Stdout},
		Username:      username,
		Password:      password,
		RetryOnStatus: []int{502, 503, 504, 429},
		RetryBackoff: func(i int) time.Duration {
			if i == 1 {
				retryBackoff.Reset()
			}
			return retryBackoff.NextBackOff()
		},
		MaxRetries: 5,
		Transport: &DecoratedTransport{
			tp: &http.Transport{
				Proxy: http.ProxyFromEnvironment,
				DialContext: (&net.Dialer{
					Timeout:   30 * time.Second,
					KeepAlive: 30 * time.Second,
				}).DialContext,
				ForceAttemptHTTP2:     true,
				MaxIdleConns:          100,
				IdleConnTimeout:       90 * time.Second,
				TLSHandshakeTimeout:   10 * time.Second,
				ExpectContinueTimeout: 1 * time.Second,
				TLSClientConfig: &tls.Config{
					InsecureSkipVerify: true,
				},
			},
		},
	}
	return cfg
}

3 拓展

es基础概念

索引index(databse)

类型type(table),6.x后弃用

文档doc(row)

属性field(column)

curl操作es

curl localhost:9200/_cluster/health # 查看集群健康状态
curl localhost:9200/_cat/pending_tasks # 查看任务堆积详情
curl localhost:9200/_cluster/state/metadata # 查看集群元数据状态信息 
curl localhost:9200/_cluster/stats # 查看集群指标统计信息
curl localhost:9200/_cluster/allocation/explain # 查看集群分片分配详情
curl localhost:9200/_cluster/allocation/explain #查看集群分片分配详情
curl http://localhost:9200/test-*/_count # 统计文档总数(记录数)
curl localhost:9200/_cluster/settings # 查看集群settings信息
curl localhost:9200/_tasks
curl http://localhost:9200/test-ziyi-1-100000-218/_mapping # 查看索引信息
curl -X GET "http://es.test.ziyi.com/test-ziyi-1-100004-100136/_doc/1?pretty" # 查询id为1的文档记录
curl http://localhost:9200/_cat/indices?v # 查看各个索引记录数,?v带上表头,展示详细信息
curl  -X DELETE "http://192.168.100.88:9200/my_index" # 删除索引(包含索引结构)
# 删除索引数据不包含索引结构
curl -X POST \
     -H 'Content-Type: application/json' \
     -d '{"query":{"match_all":{}}}' \
     'http://localhost:9200/test-ziyi-metadata-1-100004-100136/_delete_by_query?pretty=true' 

# 进入es pod,执行查询命令
curl -X POST "http://your_elasticsearch_host:9200/test-ziyi-metadata-1-10000-3/_search" -H 'Content-Type: application/json' -d '
{
  "size": 100,
  "sort": [
    { "mtime": { "order": "desc" } },
    { "key": { "order": "desc" } }
  ],
  "query": {
    "range": {
      "size": {
        "gt": 10485760
      }
    }
  }
}'

例如:查看索引信息
在这里插入图片描述

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

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

相关文章

一 GD32 MCU 开发环境搭建

GD32 系列为通用型 MCU &#xff0c;所以开发环境也可以使用通用型的 IDE &#xff0c;目前使用较多的是 KEIL、 IAR 、 GCC 和 Embedded Builder &#xff0c;客户可以根据个人喜好来选择相应的开发环境。 目录 1、使用 Keil 开发 GD32 目前市面通用的MDK for ARM版本有Kei…

Java代码初始化块

目录 实例域代码块 静态域代码块 初始化代码块分为静态域代码块和实例域代码块&#xff0c;静态域代码块在类第一次被加载时被执行&#xff0c;实例域代码块在创建对象时被执行&#xff0c;一个类中可以有多个代码块。 实例域代码块 使用方法 可以有输出语句 可以对类的属…

02. Hibernate 初体验之持久化对象

1. 前言 本节课程让我们一起体验 Hibernate 的魅力&#xff01;编写第一个基于 Hibernate 的实例程序。 在本节课程中&#xff0c;你将学到 &#xff1a; Hibernate 的版本发展史&#xff1b;持久化对象的特点。 为了更好地讲解这个内容&#xff0c;这个初体验案例分上下 2…

自学第十六天----深入理解函数中

4. 函数的调用&#xff1a; 4.1 传值调用 函数的形参和实参分别占有不同内存块&#xff0c;对形参的修改不会影响实参。 4.2 传址调用 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。 这种传参方式可以让函数和函数外边的变量建立起真正的联系&…

在 vite+vue3+electron 中使用 express

文章目录 一、Vite Vue3 Electron 项目的搭建二、搭建 express 环境1、安装 express 框架所需依赖2、创建 express 项目3、配置路由4、启动 express 服务5、启动 electron 并获取数据 三、项目打包 一、Vite Vue3 Electron 项目的搭建 详细的项目构建和打包可参考另一篇文…

【第32章】MyBatis-Plus之代码生成器配置

文章目录 前言一、概述1.特点说明2.示例配置3. 数据库配置 (DataSourceConfig) 二、全局配置 (GlobalConfig)1.方法说明2.示例配置 三、包配置 (PackageConfig)1. 方法说明2. 示例配置 四、模板配置 (TemplateConfig)1. 方法说明2. 示例配置 五、注入配置 (InjectionConfig)1. …

第三期书生大模型实战营之Python前置知识

闯关任务1 请实现一个wordcount函数&#xff0c;统计英文字符串中每个单词出现的次数。返回一个字典&#xff0c;key为单词&#xff0c;value为对应单词出现的次数。 算法流程 1. 去除标点&#xff1a;使用string.punctuation和str.translate去除文本中的标点符号。 2. 转换…

制造业ERP源码 ERP系统源码 ERP小程序源码

制造业ERP源码 ERP系统源码 ERP小程序源码 资料&#xff1a; 委外工厂管理 客户列表 车间管理 供应商管理 账户管理 商品管理 仓库管理 职员管理 自取地址管理 司机管理 辅助资料 客户等级 供应商分类 客户分类 商品分类 支出类别管理 收入类别管…

第一次构建一个对话机器人流程解析(一)

1.问答机器人的组成 1.1 问答机器人的组成结构图 2. 问答机器人的组成-机器人的个人属性 所谓的机器人一般具备有个人的属性&#xff0c;这些属性固定&#xff0c;形成了机器人的个人偏好 在实现过程中&#xff0c;此处使用一个xml配置文件&#xff0c;配置了机器人的个人年…

Jetbrains IDEA中Git常用操作

Git简介与使用 Intro Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. Git是一款分布式版本控制系统&#xff08;VSC&#xff09;&#xff0c;是团队合作开发…

通信协议 | 一文玩转UART协议就够了

文章目录 协议基础1、UART简介2、UART特性3、UART协议帧3.1、起始位3.2、数据位3.3、奇偶校验位3.4、停止位 4、UART通信步骤 最详细的UART通讯协议分析Verilog代码实现UART接口模块驱动 协议基础 1、UART简介 UART&#xff08;Universal Asynchronous Receiver/Transmitter&…

注意!避免计算组覆盖!

问题描述&#xff1a; PowerBI在实际使用中&#xff0c;针对于某些数据&#xff0c;需要呈现文本类型的标签&#xff0c;一般这类需求&#xff0c;都是通过计算组来解决的。 但计算组在使用中&#xff0c;也会存在一些问题&#xff0c;就是一旦点击交互&#xff0c;就会影响到其…

vue 自定义滚动条同步拖动(移动端)

实现效果&#xff0c;拖动左右箭头实现图片区域同步滚动&#xff0c;到边缘停止拖动。 HTML代码 <template><div touchstart"onClick"><!--使用draggable组件 图片列表区域--><draggablev-model"select_list"end"onEnd"cl…

2024软件测试面试题汇总【备战金九银十】内容较长建议收藏

一、面试基础题 简述测试流程: 1、阅读相关技术文档&#xff08;如产品PRD、UI设计、产品流程图等&#xff09;。 2、参加需求评审会议。 3、根据最终确定的需求文档编写测试计划。 4、编写测试用例&#xff08;等价类划分法、边界值分析法等&#xff09;。 5、用例评审(…

鸿蒙语言基础类库:【@ohos.convertxml (xml转换JavaScript)】

xml转换JavaScript 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 …

【Python】日期和时间模块

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️Python】 文章目录 前言时间元组datetime 模块datetime类获取当前日期和时间 timedelta类日期和时间运算 strftime()方法格式化时间日期格式化符号 strptime()方法 Time 模块Time 模块内置函数Time 模…

牛客小白月赛98 (个人题解)(待补完)

前言&#xff1a; 昨天晚上自己一个人打的小白月赛&#xff08;因为准备数学期末已经写烦了&#xff09;&#xff0c;题目难度感觉越来越简单了&#xff08;不在像以前一样根本写不了一点&#xff0c;现在看题解已经能看懂一点了&#xff09;&#xff0c;能感受到自己在不断进步…

LLM基础模型系列:Prompt-Tuning

------->更多内容&#xff0c;请移步“鲁班秘笈”&#xff01;&#xff01;<------ 大型预训练语言模型的规模不断扩大&#xff0c;在许多自然语言处理 &#xff08;NLP&#xff09; 基准测试中取得了最先进的结果。自GPT和BERT开发以来&#xff0c;标准做法一直是在下游…

802.11ax RU - 传输的最小单元

子载波 无线信号是加载在某个固定频率上进行传输的&#xff0c;这个频率被称为载波。802.11标准中&#xff0c;对传输频率有更新的划分&#xff0c;而这些划分的频率被称为子载波。Wi-Fi 6中&#xff0c;以20Mhz信道为例&#xff0c;20Mhz信道被划分成256个子载波&#xff0c;…

Go-知识测试-子测试

Go-知识测试-子测试 1. 介绍2. 例子3. 子测试命名规则4. 选择性执行5. 子测试并发6. testing.T.Run7. testing.T.Parallel8. 子测试适用于单元测试9. 子测试适用于性能测试10. 总结10.1 启动子测试 Run10.2 启动并发测试 Parallel 建议先看&#xff1a;https://blog.csdn.net/a…