主頁 >  其他 > 谷粒商城_06_JSR303校驗+Elasticsearch

谷粒商城_06_JSR303校驗+Elasticsearch

2021-12-20 07:13:15 其他

文章目錄

  • JSR303校驗
    • 普通校驗
    • 區域例外處理BindResult
    • 統一例外處理
  • 分組校驗功能(多場景校驗)
  • 自定義校驗注解
  • Elasticsearch
    • 初步檢索
      • 1、檢索es資訊
      • 2、新增檔案
        • PUT和POST區別
      • 3、查看檔案
      • 4、更新檔案_update
      • 5、洗掉檔案或索引
        • 洗掉索引
      • 6、ES的批量操作——bulk
      • 7、樣本測驗資料

谷粒商城_01_環境搭建
谷粒商城_02_Nacos、網關
谷粒商城_03_前端基礎
谷粒商城_04_商品CRUD
谷粒商城_05_阿里云OSS和前端校驗

JSR303校驗

問題引入:填寫form時應該有前端校驗,后端也應該有校驗

前端的校驗是element-ui表單驗證:https://element.eleme.cn/#/zh-CN/component/form

  • Form 組件提供了表單驗證的功能,只需要通過 rules 屬性傳入約定的驗證規則,并將 Form-Item 的 prop 屬性設定為需校驗的欄位名即可,校驗規則參見 async-validator

  • 使用自定義校驗規則可以解決字母限制、密碼不一致、非整數限制等等的問題

  • 基本使用

    // dataForm:表單的資料、dataRule:所有檢驗的規則
    <el-form :model="dataForm" :rules="dataRule"/>
        
    // 表單的某一項用prop指定校驗的目標即可使用
    <el-form-item label="密碼" prop="checkPass">
    
    // 
    data() {
    	return {
        	dataRule: {
                // 密碼校驗的欄位checkPass,validator: validatePass指向校驗的具體方法,既可以將其替換成方法使用
            	checkPass: [
                { validator: validatePass, trigger: 'blur' }
            	],
            }
        }
    }
    var validatePass = (rule, value, callback) => {
        if (value === '') {
            callback(new Error('請再次輸入密碼'));
            // dataForm表單的資料
        } else if (value !== this.dataForm.pass) {
            callback(new Error('兩次輸入密碼不一致!'));
        } else {
            callback();
        }
    };
    
  • 后端:@NotNull、@NotBank、@URL等等

普通校驗

1、使用校驗注解

在Java中提供了一系列的校驗方式,它這些校驗方式在“javax.validation.constraints、org.hibernate.validator.constraints”包中,提供了如@Email、@NotNull、@URL等注解,

  • 主要看注解原始碼檔案來了解其中使用
<!--jsr3引數校驗器-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>2.6.1</version>
</dependency>

2、@Valid內置例外

這里內置例外的意思是發生例外時回傳的json不是我們的R物件,而是mvc的內置類

在controller類上加:@Validated,方法引數中加校驗注解:@Valid,開啟校驗,

@RequestMapping("/save")
public R save(@Valid @RequestBody BrandEntity brand){
    brandService.save(brand);

    return R.ok();
}

測驗: http://localhost:88/api/product/brand/save,在postman種發送上面的請求,發現回傳的是json物件,但不是我們的R物件

 // 其中
"defaultMessage": "不能為空",

“defaultMessage”: “不能為空”,這些錯誤訊息定義在“hibernate-validator”的“\org\hibernate\validator\ValidationMessages_zh_CN.properties”檔案中,在該檔案中定義了很多的錯誤規則:

javax.validation.constraints.AssertFalse.message     = 只能為false
javax.validation.constraints.AssertTrue.message      = 只能為true
javax.validation.constraints.DecimalMax.message      = 必須小于或等于{value}
javax.validation.constraints.DecimalMin.message      = 必須大于或等于{value}
javax.validation.constraints.Digits.message          = 數字的值超出了允許范圍(只允許在{integer}位整數和{fraction}位小數范圍內)
javax.validation.constraints.Email.message           = 不是一個合法的電子郵件地址
javax.validation.constraints.Future.message          = 需要是一個將來的時間
javax.validation.constraints.FutureOrPresent.message = 需要是一個將來或現在的時間
javax.validation.constraints.Max.message             = 最大不能超過{value}
javax.validation.constraints.Min.message             = 最小不能小于{value}
javax.validation.constraints.Negative.message        = 必須是負數
javax.validation.constraints.NegativeOrZero.message  = 必須是負數或零
javax.validation.constraints.NotBlank.message        = 不能為空
javax.validation.constraints.NotEmpty.message        = 不能為空
javax.validation.constraints.NotNull.message         = 不能為null
javax.validation.constraints.Null.message            = 必須為null
javax.validation.constraints.Past.message            = 需要是一個過去的時間
javax.validation.constraints.PastOrPresent.message   = 需要是一個過去或現在的時間
javax.validation.constraints.Pattern.message         = 需要匹配正則運算式"{regexp}"
javax.validation.constraints.Positive.message        = 必須是正數
javax.validation.constraints.PositiveOrZero.message  = 必須是正數或零
javax.validation.constraints.Size.message            = 個數必須在{min}{max}之間

org.hibernate.validator.constraints.CreditCardNumber.message        = 不合法的信用卡號碼
org.hibernate.validator.constraints.Currency.message                = 不合法的貨幣 (必須是{value}其中之一)
org.hibernate.validator.constraints.EAN.message                     = 不合法的{type}條形碼
org.hibernate.validator.constraints.Email.message                   = 不是一個合法的電子郵件地址
org.hibernate.validator.constraints.Length.message                  = 長度需要在{min}{max}之間
org.hibernate.validator.constraints.CodePointLength.message         = 長度需要在{min}{max}之間
org.hibernate.validator.constraints.LuhnCheck.message               = ${validatedValue}的校驗碼不合法, Luhn10校驗和不匹配
org.hibernate.validator.constraints.Mod10Check.message              = ${validatedValue}的校驗碼不合法,10校驗和不匹配
org.hibernate.validator.constraints.Mod11Check.message              = ${validatedValue}的校驗碼不合法,11校驗和不匹配
org.hibernate.validator.constraints.ModCheck.message                = ${validatedValue}的校驗碼不合法, ${modType}校驗和不匹配
org.hibernate.validator.constraints.NotBlank.message                = 不能為空
org.hibernate.validator.constraints.NotEmpty.message                = 不能為空
org.hibernate.validator.constraints.ParametersScriptAssert.message  = 執行腳本運算式"{script}"沒有回傳期望結果
org.hibernate.validator.constraints.Range.message                   = 需要在{min}{max}之間
org.hibernate.validator.constraints.SafeHtml.message                = 可能有不安全的HTML內容
org.hibernate.validator.constraints.ScriptAssert.message            = 執行腳本運算式"{script}"沒有回傳期望結果
org.hibernate.validator.constraints.URL.message                     = 需要是一個合法的URL

org.hibernate.validator.constraints.time.DurationMax.message        = 必須小于${inclusive == true ? '或等于' : ''}${days == 0 ? '' : days += '天'}${hours == 0 ? '' : hours += '小時'}${minutes == 0 ? '' : minutes += '分鐘'}${seconds == 0 ? '' : seconds += '秒'}${millis == 0 ? '' : millis += '毫秒'}${nanos == 0 ? '' : nanos += '納秒'}
org.hibernate.validator.constraints.time.DurationMin.message        = 必須大于${inclusive == true ? '或等于' : ''}${days == 0 ? '' : days += '天'}${hours == 0 ? '' : hours += '小時'}${minutes == 0 ? '' : minutes += '分鐘'}${seconds == 0 ? '' : seconds += '秒'}${millis == 0 ? '' : millis += '毫秒'}${nanos == 0 ? '' : nanos += '納秒'}

想要自定義錯誤訊息,可以覆寫默認的錯誤提示資訊,如@NotBlank的默認message是

public @interface NotBlank {
	String message() default "{javax.validation.constraints.NotBlank.message}";
}

可以在添加注解的時候,修改message:

@NotBlank(message = "品牌名必須非空")
private String name;

當再次發送請求時,得到的錯誤提示資訊:

"defaultMessage": "品牌名必須非空",

但是回傳的錯誤不是R物件,影響接收端的接收,我們可以通過區域例外處理或者統一一次處理解決

區域例外處理BindResult

  • 給校驗的Bean后,緊跟一個BindResult,就可以獲取到校驗的結果,拿到校驗的結果,就可以自定義的封裝,
@RequestMapping("/save")
public R save(@Valid @RequestBody BrandEntity brand,
              BindingResult result){ // 手動處理例外

    if( result.hasErrors()){
        Map<String,String> map=new HashMap<>();
        //1.獲取錯誤的校驗結果
        result.getFieldErrors().forEach((item)->{
            //獲取發生錯誤時的message,提示資訊
            String message = item.getDefaultMessage();
            //獲取發生錯誤的屬性的名字
            String field = item.getField();
            map.put(field,message);
        });
        return R.error(400,"提交的資料不合法").put("data",map);
    }else {

    }
    brandService.save(brand);
    return R.ok();
}

這種是針對于該請求設定了一個內容校驗,如果針對于每個請求都單獨進行配置,顯然不是太合適,實際上可以統一的對于例外進行處理,

統一例外處理

@ExceptionHandler

  • @ ExceptionHandler 需要進行例外處理的方法必須與出錯的方法在同一個Controller里面,那么當代碼加入了 @ControllerAdvice,則不需要必須在同一個 controller 中了,這也是 Spring 3.2 帶來的新特性, 也就是說,@controlleradvice + @ ExceptionHandler 也可以實作全域的例外捕捉,

1、抽取一個例外處理類

  • @ControllerAdvice標注在類上,通過“basePackages”能夠說明處理哪些路徑下的例外,
  • @ExceptionHandler(value = 例外型別.class)標注在方法上
  • 這里的ConstraintViolationException例外我和專案中不一樣,但是可以通過原始碼定位到里面的屬性,然后獲取例外資訊放入map
/**
 * @author ljy
 * @version 1.0.0
 * @Description 集中處理所有例外
 * @createTime 2021年12月14日 19:22:00
 */
@Slf4j
// @RestControllerAdvice和@ControllerAdvice的關系類似于@RestController
@RestControllerAdvice(basePackages = "com.liu.gulimall.product.controller")// 管理的controller
public class GulimallExceptionControllerAdvice {

    @ExceptionHandler(value = ConstraintViolationException.class) // 感知精確例外
    // 也可以回傳ModelAndView
    // exception是controller中的例外,精確匹配ConstraintViolationException這個例外
    // MethodArgumentNotValidException
    public R handleValidException(ConstraintViolationException exception){
        Map<String,String> map=new HashMap<>();
        // 獲取資料校驗的錯誤結果,和之前一樣BindingResult
        exception.getConstraintViolations().forEach(item->{
            String message = item.getMessage();
            Path propertyPath = item.getPropertyPath();
            map.put(propertyPath.toString(),message);
        });

        log.error("資料校驗出現問題{},例外型別{}",exception.getMessage(),exception.getClass());

        return R.error(400,"資料校驗出現問題").put("data",map);
    }

    @ExceptionHandler(value = Throwable.class)//例外的范圍更大
    public R handleException(Throwable throwable){
        log.error("未知例外{},例外型別{}",
                throwable.getMessage(),
                throwable.getClass());
        return R.error(BizCodeEnum.UNKNOW_EXEPTION.getCode(),
                BizCodeEnum.UNKNOW_EXEPTION.getMsg());
    }
}

(2)測驗: http://localhost:9999/product/brand/save

在這里插入圖片描述

(3)默認例外處理

@ExceptionHandler(value = Throwable.class)// 例外的范圍更大
public R handleException(Throwable throwable){
    log.error("未知例外{},例外型別{}",
              throwable.getMessage(),
              throwable.getClass());
    return R.error(BizCodeEnum.UNKNOW_EXEPTION.getCode(),
                   BizCodeEnum.UNKNOW_EXEPTION.getMsg());
}

(4)錯誤狀態碼

正規開發程序中,錯誤狀態碼有著嚴格的定義規則,在專案中我們的錯誤狀態碼定義

上面的用法主要是通過@Controller+@ExceptionHandler來進行例外攔截處理,單獨定義一個列舉類,用來存盤這些錯誤狀態碼

/***
 * 錯誤碼和錯誤資訊定義類
 * 1. 錯誤碼定義規則為5為數字
 * 2. 前兩位表示業務場景,最后三位表示錯誤碼,例如:10001,10:通用 001:系統未知例外
 * 3. 維護錯誤碼后需要維護錯誤描述,將他們定義為列舉形式
 * 錯誤碼串列:
 *  10: 通用
 *      001:引數格式校驗
 *  11: 商品
 *  12: 訂單
 *  13: 購物車
 *  14: 物流
 */
/**
 * @author ljy
 * @version 1.0.0
 * @Description TODO
 * @createTime 2021年12月14日 19:23:00
 */
public enum BizCodeEnum {

    UNKNOW_EXEPTION(10000,"系統未知例外"),

    VALID_EXCEPTION( 10001,"引數格式校驗失敗");

    private int code;
    private String msg;

    BizCodeEnum(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

分組校驗功能(多場景校驗)

前面解決了統一例外處理,但是同一物體比如id,修改的時候不能為空,添加的時候為空,那怎么來校驗呢?

我們采取分組的方式

1、定義分組介面,A(添加分組)、B(洗掉分組),介面只是標識

2、在controller方法中添加的方法中使用 @Validated(A.class)

// 表示添加的時候采用A分組策略
public R save(@Validated({A.class}) @RequestBody BrandEntity brand){

3、在物體屬性上,比如id,@NotNull(message = “修改id不為空”,groups = {B.class})、@Null(message = “新增id必須為空”,groups = {A.class})

@NotNull(message = "修改必須定制品牌id", groups = {UpdateGroup.class})
@Null(message = "新增不能指定id", groups = {AddGroup.class})
@TableId
private Long brandId;

在這種情況下,沒有指定分組的校驗注解,默認是不起作用的,想要起作用就必須要加groups,

  • controller接收到之后,根據@Validated表明的分組資訊,然后確定品牌對應的校驗注解,

總結:

package com.liu.common.valid;

/**
 * @author ljy
 * @version 1.0.0
 * @Description TODO
 * @createTime 2021年12月14日 20:49:00
 */
public interface addGroup {
}
========================
/**
 * 保存
 */
@RequestMapping("/save")
public R save(@Validated({addGroup.class}) @RequestBody BrandEntity brand, BindingResult result){
    brandService.save(brand);
    return R.ok();
}
========================
/**
 * 品牌名
 */
@NotBlank(message = "品牌名不能為空", groups  = {addGroup.class})
private String name;
========================
{
    "msg": "提交的資料不合法",
    "code": 400,
    "data": {
        "name": "品牌名不能為空"
    }
}

自定義校驗注解

Hibernate Validator提供了一系列內置的校驗注解,可以滿足大部分的校驗需求,但是,仍然有一部分校驗需要特殊定制

比如:要校驗showStatus的0/1狀態,只能是0,1兩個值

1、添加依賴

<!--校驗-->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.1.0.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.4.1.Final</version>
</dependency>
<!--高版本需要javax.el-->
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.el</artifactId>
    <version>3.0.1-b08</version>
</dependency>

2、自定義注解

/**
 * @author ljy
 * @version 1.0.0
 * @Description 自定義注解,模仿其他的檢驗注解即可
 * @createTime 2021年12月14日 20:57:00
 */
@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class}) // 校驗器,指定校驗器,需要我們自己定義
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) // 在哪可以標注此注解
@Retention(RUNTIME)
public @interface ListValue {
    // 必須有3個屬性
    // 使用該屬性去Validation.properties中取
    String message() default "{com.liu.common.valid.ListValue.message}"; // 錯誤資訊

    Class<?>[] groups() default { }; // 分組校驗

    Class<? extends Payload>[] payload() default { }; // 自定義負載資訊

    // 陣列,需要用戶自己指定
    int[] value() default {};
}

因為上面的message值對應的最終字串需要去ValidationMessages.properties中獲得,所以我們在common中新建檔案ValidationMessages.properties

3、ValidationMessages.properties

com.liu.common.valid.ListValue.message=必須提交指定的值 [0,1]

4、自定義校驗器

  • 通過原始碼:@Constraint注解的validatedBy是一個ConstraintValidator型別,并且里面包含了注解和校驗型別,所以我們自定義實作ConstraintValidator,放入我們的注解和型別
/**
 * @author ljy
 * @version 1.0.0
 * @Description TODO
 * @createTime 2021年12月14日 21:06:00
 */
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
    // 存盤所有可能的值
    private Set<Integer> set=new HashSet<Integer>();

    // 初始化,你可以獲取注解上的內容并進行處理
    public void initialize(ListValue constraintAnnotation) {
        // 獲取后端寫好的限制 // 這個value就是ListValue里的value,我們寫的注解是@ListValue(value={0,1})
        int[] value = constraintAnnotation.value();
        for (int i : value) {
            set.add(i);
        }
    }

    /**
     * 覆寫驗證邏輯
     * @param value 需要校驗的值
     * @param context
     * @return
     */
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        // 看是否在限制的值里,是回傳true
        return  set.contains(value);
    }
}

5、使用

/**
 * 顯示狀態[0-不顯示;1-顯示]
 */
@ListValue(value = {0,1},groups ={addGroup.class})
private Integer showStatus;

6、測驗

{
    "msg": "提交的資料不合法",
    "code": 400,
    "data": {
        "showStatus": "必須提交指定的值 [0,1]"
    }
}

在這里插入圖片描述

Elasticsearch

初步檢索

1、檢索es資訊

(1)GET /_cat/nodes:查看所有節點 :http://localhost:9200/_cat/nodes

(2)GET /_cat/health:查看es健康狀況:green表示健康值正常

(3)GET /_cat/master:查看主節點

(4)GET/_cat/indicies:查看所有索引 ,等價于mysql資料庫的show databases;

2、新增檔案

保存一個資料,保存在哪個索引的哪個型別下(哪張資料庫哪張表下),保存時用唯一標識指定

# 在customer索引下的external型別下保存1號資料
PUT customer/external/1

{
 "name":"John Doe"
}

PUT和POST區別

  • POST新增,如果不指定id,會自動生成id,指定id就會修改這個資料,并新增版本號;
    • 可以不指定id,不指定id時永遠為創建
    • 指定不存在的id為創建
    • 指定存在的id為更新,而版本號會根據內容變沒變而覺得版本號遞增與否
  • PUT可以新增也可以修改,PUT必須指定id;由于PUT需要指定id,我們一般用來做修改操作,不指定id會報錯,
    • 必須指定id
    • 版本號總會增加

seq_no和version的區別:

  • 每個檔案的版本號"_version" 起始值都為1 每次對當前檔案成功操作后都加1
  • 而序列號"_seq_no"則可以看做是索引的資訊 在第一次為索引插入資料時為0,每對索引內資料操作成功一次sqlNO加1, 并且檔案會記錄是第幾次操作使它成為現在的情況的

下面是在postman中選用POST方式的測驗資料:

創建資料成功后,顯示201 created表示插入記錄成功,

回傳資料:
帶有下劃線開頭的,稱為元資料,反映了當前的基本資訊,  
{
    "_index": "customer", 表明該資料在哪個資料庫下;
    "_type": "external", 表明該資料在哪個型別下;
    "_id": "1",  表明被保存資料的id;
    "_version": 1,  被保存資料的版本
    "result": "created", 這里是創建了一條資料,如果重新put一條資料,則該狀態會變為updated,并且版本號也會發生變化,
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}
12345678910111213141516

下面選用POST方式:

添加資料的時候,不指定ID,會自動的生成id,并且型別是新增:

{
    "_index": "customer",
    "_type": "external",
    "_id": "5MIjvncBKdY1wAQm-wNZ",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 11,
    "_primary_term": 6
}
1234567891011121314

再次使用POST插入資料,不指定ID,仍然是新增的:

{
    "_index": "customer",
    "_type": "external",
    "_id": "5cIkvncBKdY1wAQmcQNk",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 12,
    "_primary_term": 6
}

添加資料的時候,指定ID,會使用該id,并且型別是新增:

{
    "_index": "customer",
    "_type": "external",
    "_id": "2",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 13,
    "_primary_term": 6
}

再次使用POST插入資料,指定同樣的ID,型別為updated

{
    "_index": "customer",
    "_type": "external",
    "_id": "2",
    "_version": 2,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 14,
    "_primary_term": 6
}

3、查看檔案

GET /customer/external/1

{
    "_index": "customer",
    "_type": "external",
    "_id": "1",
    "_version": 10,
    "_seq_no": 18,//并發控制欄位,每次更新都會+1,用來做樂觀鎖
    "_primary_term": 6,//同上,主分片重新分配,如重啟,就會變化
    "found": true,
    "_source": {
        "name": "John Doe"
    }
}
123456789101112

樂觀鎖用法:通過“if_seq_no=1&if_primary_term=1”,當序列號匹配的時候,才進行修改,否則不修改,

實體:將id=1的資料更新為name=1,然后再次更新為name=2,起始1_seq_no=18,_primary_term=6

(1)將name更新為1

PUT http://localhost:9200/customer/external/1?if_seq_no=18&if_primary_term=6

(2)將name更新為2,更新程序中使用seq_no=18

PUT http://localhost:9200/customer/external/1?if_seq_no=18&if_primary_term=6

結果為:出現更新錯誤,

(3)查詢新的資料

GET http://localhost:9200/customer/external/1

{
    "_index": "customer",
    "_type": "external",
    "_id": "1",
    "_version": 11,
    "_seq_no": 19,
    "_primary_term": 6,
    "found": true,
    "_source": {
        "name": "1"
    }
}

能夠看到_seq_no變為19

(4)再次更新,更新成功

4、更新檔案_update

POST customer/externel/1/_update
{
    "doc":{
        "name":"111"
    }
}
或者
POST customer/externel/1
{
    "doc":{
        "name":"222"
    }
}
或者
PUT customer/externel/1
{
    "doc":{
        "name":"222"
    }
}

不同:帶有update情況下

  • POST操作會對比源檔案資料,如果相同不會有什么操作,檔案version不增加,
  • PUT操作總會重新保存并增加version版本

POST時帶_update對比元資料如果一樣就不進行任何操作,

看場景:

  • 對于大并發更新,不帶update
  • 對于大并發查詢偶爾更新,帶update;對比更新,重新計算分配規則

(1)POST更新檔案,帶有_update

如果再次執行更新,則不執行任何操作,序列號也不發生變化

回傳
{
    "_index": "customer",
    "_type": "external",
    "_id": "1",
    "_version": 12,
    "result": "noop", // 無操作
    "_shards": {
        "total": 0,
        "successful": 0,
        "failed": 0
    },
    "_seq_no": 20,
    "_primary_term": 6
}

POST更新方式,會對比原來的資料,和原來的相同,則不執行任何操作(version和_seq_no)都不變,

(2)POST更新檔案,不帶_update,和put一樣

在更新程序中,重復執行更新操作,資料也能夠更新成功,不會和原來的資料進行對比,

{
    "_index": "customer",
    "_type": "external",
    "_id": "1",
    "_version": 13,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 21,
    "_primary_term": 6
}

5、洗掉檔案或索引

DELETE customer/external/1
DELETE customer // 洗掉索引

注:elasticsearch并沒有提供洗掉型別的操作,只提供了洗掉索引和檔案的操作,

實體:洗掉id=1的資料,洗掉后繼續查詢

DELETE http://localhost:9200/customer/external/1

{
    "_index": "customer",
    "_type": "external",
    "_id": "1",
    "_version": 14,
    "result": "deleted",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 22,
    "_primary_term": 6
}

再次執行DELETE http://localhost:9200/customer/external/1

{
    "_index": "customer",
    "_type": "external",
    "_id": "1",
    "_version": 15,
    "result": "not_found",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 23,
    "_primary_term": 6
}

GET http://localhost:9200/customer/external/1

{
    "_index": "customer",
    "_type": "external",
    "_id": "1",
    "found": false
}
123456

洗掉索引

實體:洗掉整個costomer索引資料

洗掉前,所有的索引http://localhost:9200/_cat/indices

green  open .kibana_task_manager_1   DhtDmKrsRDOUHPJm1EFVqQ 1 0 2 0 31.3kb 31.3kb
green  open .apm-agent-configuration vxzRbo9sQ1SvMtGkx6aAHQ 1 0 0 0   283b   283b
green  open .kibana_1                rdJ5pejQSKWjKxRtx-EIkQ 1 0 8 3 28.8kb 28.8kb
yellow open customer                 mG9XiCQISPmfBAmL1BPqIw 1 1 9 1  8.6kb  8.6kb

洗掉“ customer ”索引

DELTE http://localhost:9200/customer

回應
{
    "acknowledged": true
}

洗掉后,所有的索引 http://localhost:9200/_cat/indices

green open .kibana_task_manager_1   DhtDmKrsRDOUHPJm1EFVqQ 1 0 2 0 31.3kb 31.3kb
green open .apm-agent-configuration vxzRbo9sQ1SvMtGkx6aAHQ 1 0 0 0   283b   283b
green open .kibana_1                rdJ5pejQSKWjKxRtx-EIkQ 1 0 8 3 28.8kb 28.8kb

6、ES的批量操作——bulk

匹配匯入資料

POST http://localhost:9200/customer/external/_bulk

兩行為一個整體
{"index":{"_id":"1"}}
{"name":"a"}
{"index":{"_id":"2"}}
{"name":"b"}
注意格式json和text均不可,要去kibana里Dev Tools

語法格式:

{action:{metadata}}\n
{request body  }\n

{action:{metadata}}\n
{request body  }\n

這里的批量操作,當發生某一條執行發生失敗時,其他的資料仍然能夠接著執行,也就是說彼此之間是獨立的,

bulk api以此按順序執行所有的action(動作),如果一個單個的動作因任何原因失敗,它將繼續處理它后面剩余的動作,當bulk api回傳時,它將提供每個動作的狀態(與發送的順序相同),所以您可以檢查是否一個指定的動作是否失敗了,

實體1: 執行多條資料

POST /customer/external/_bulk
{"index":{"_id":"1"}}
{"name":"John Doe"}
{"index":{"_id":"2"}}
{"name":"John Doe"}
12345

執行結果

#! Deprecation: [types removal] Specifying types in bulk requests is deprecated.
{
  "took" : 318,  花費了多少ms
  "errors" : false, 沒有發生任何錯誤
  "items" : [ 每個資料的結果
    {
      "index" : { 保存
        "_index" : "customer", 索引
        "_type" : "external", 型別
        "_id" : "1", 檔案
        "_version" : 1, 版本
        "result" : "created", 創建
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201 新建完成
      }
    },
    {
      "index" : { 第二條記錄
        "_index" : "customer",
        "_type" : "external",
        "_id" : "2",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 1,
        "_primary_term" : 1,
        "status" : 201
      }
    }
  ]
}

實體2:對于整個索引執行批量操作

POST /_bulk
{"delete":{"_index":"website","_type":"blog","_id":"123"}}
{"create":{"_index":"website","_type":"blog","_id":"123"}}
{"title":"my first blog post"}
{"index":{"_index":"website","_type":"blog"}}
{"title":"my second blog post"}
{"update":{"_index":"website","_type":"blog","_id":"123"}}
{"doc":{"title":"my updated blog post"}}

7、樣本測驗資料

準備了一份顧客銀行賬戶資訊的虛構的JSON檔案樣本,每個檔案都有下列的schema(模式),

{
	"account_number": 1,
	"balance": 39225,
	"firstname": "Amber",
	"lastname": "Duke",
	"age": 32,
	"gender": "M",
	"address": "880 Holmes Lane",
	"employer": "Pyrami",
	"email": "amberduke@pyrami.com",
	"city": "Brogan",
	"state": "IL"
}

https://github.com/elastic/elasticsearch/blob/master/docs/src/test/resources/normalized-T1117-AtomicRed-regsvr32.json ,匯入測驗資料,

POST bank/account/_bulk
上面的資料
http://localhost:9200/_cat/indices
付訓入了1000條
yellow open bank                     99m64ElxRuiH46wV7RjXZA 1 1 1000 0 427.8kb 427.8kb

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/386525.html

標籤:其他

上一篇:Mysiam和Innodb引擎區別

下一篇:MQ那點破事,訊息丟失、重復消費、消費順序、堆積、事務、高可用....

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more