Elasticsearch:介绍 kNN query,这是进行 kNN 搜索的专家方法

作者:来自 Elastic Mayya Sharipova, Benjamin Trent

当前状况:kNN 搜索作为顶层部分

Elasticsearch 中的 kNN 搜索被组织为搜索请求的顶层(top level)部分。 我们这样设计是为了:

  • 无论分片数量多少,它总是可以返回全局 k 个最近邻居
  • 这些全局 k 个结果与其他查询的结果相结合以形成混合搜索
  • 全局 k 结果被传递到聚合以形成统计(facets)。

这是 kNN 搜索在内部执行的简化图(省略了一些阶段):

图 1:顶层 kNN 搜索的步骤是:

  1. 用户提交搜索请求
  2. 协调器节点在 DFS 阶段向数据节点发送请求的 kNN 搜索部分
  3. 每个数据节点运行 kNN 搜索并将本地 top-k 结果发送回协调器
  4. 协调器合并所有本地结果以形成全局前 k 个最近邻居。
  5. 协调器将全局 k 个最近邻居发送回数据节点,并提供任何其他查询
  6. 每个数据节点运行额外的查询并将本地 size 结果发送回协调器
  7. 协调器合并所有本地结果并向用户发送响应

我们首先在 DFS 阶段运行 kNN 搜索以获得全局前 k 个结果。 然后,这些全局 k 结果被传递到搜索请求的其他部分,例如其他查询或聚合。 即使执行看起来很复杂,但从用户的角度来看,运行 kNN 搜索的模型很简单,因为用户始终可以确保 kNN 搜索返回全局 k 结果。

它的请求格式如下:

GET collection-with-embeddings/_search
{
  "knn": {
    "field": "text_embedding.predicted_value",
    "query_vector_builder": {
      "text_embedding": {
        "model_id": "sentence-transformers__msmarco-distilbert-base-tas-b",
        "model_text": "How is the weather in Jamaica?"
      }
    },
    "k": 10,
    "num_candidates": 100
  },
  "_source": [
    "id",
    "text"
  ]
}

引入 kNN 查询

随着时间的推移,我们意识到还需要将 kNN 搜索表示为查询。 查询是 Elasticsearch 中搜索请求的核心组件,将 kNN 搜索表示为查询可以灵活地将其与其他查询结合起来,以解决更复杂的请求。

kNN 查询与顶层 kNN 搜索不同,没有 k 参数。 与其他查询一样,返回的结果(最近邻居)的数量由 size 参数定义。 与 kNN 搜索类似,num_candidates 参数定义在执行 kNN 搜索时在每个分片上考虑多少个候选者。

GET products/_search
{
 "size" : 3,
 "query": {
   "knn": {
     "field": "embedding",
     "query_vector": [2,2,2,0],
     "num_candidates": 10
   }
 }
}

kNN 查询的执行方式与顶层 kNN 搜索不同。 下面是一个简化图,描述了 kNN 查询如何在内部执行(省略了一些阶段):

图 2:基于查询的 kNN 搜索步骤如下:

  • 用户提交搜索请求
  • 协调器向数据节点发送一个 kNN 搜索查询,并提供附加查询
  • 每个数据节点运行查询并将本地大小结果发送回协调器节点
  • 协调器节点合并所有本地结果并向用户发送响应

我们在一个分片上运行 kNN 搜索以获得 num_candidates 结果; 这些结果将传递给分片上的其他查询和聚合,以从分片获取大小结果。 由于我们不首先收集全局 k 个最近邻居,因此在此模型中,收集的且对其他查询和聚合可见的最近邻居的数量取决于分片的数量。

kNN 查询 API 示例

让我们看一下 API 示例,这些示例演示了顶层 kNN 搜索和 kNN 查询之间的差异。

我们创建产品索引并索引一些文档:

PUT products
{
 "mappings": {
   "dynamic": "strict",
   "properties": {
     "department": {
       "type": "keyword"
     },
     "brand": {
       "type": "keyword"
     },
     "description": {
       "type": "text"
     },
     "embedding": {
       "type": "dense_vector",
       "index": true,
       "similarity": "l2_norm"
     },
     "price": {
       "type": "float"
     }
   }
 }
}
POST products/_bulk?refresh=true
{"index":{"_id":1}}
{"department":"women","brand": "Levi's", "description":"high-rise red jeans","embedding":[1,1,1,1],"price":100}
{"index":{"_id":2}}
{"department":"women","brand": "Calvin Klein","description":"high-rise beautiful jeans","embedding":[1,1,1,1],"price":250}
{"index":{"_id":3}}
{"department":"women","brand": "Gap","description":"every day jeans","embedding":[1,1,1,1],"price":50}
{"index":{"_id":4}}
{"department":"women","brand": "Levi's","description":"jeans","embedding":[2,2,2,0],"price":75}
{"index":{"_id":5}}
{"department":"women","brand": "Levi's","description":"luxury jeans","embedding":[2,2,2,0],"price":150}
{"index":{"_id":6}}
{"department":"men","brand": "Levi's", "description":"jeans","embedding":[2,2,2,0],"price":50}
{"index":{"_id":7}}
{"department":"women","brand": "Levi's", "description":"jeans 2023","embedding":[2,2,2,0],"price":150}

kNN 查询类似于顶层 kNN 搜索,具有 num_candidates 和充当预过滤器的内部 filter 参数。

GET products/_search?filter_path=**.hits
{
 "size" : 3,
 "query": {
   "knn": {
     "field": "embedding",
     "query_vector": [2,2,2,0],
     "num_candidates": 10,
     "filter" : {
       "term" : {
         "department" : "women"
       }
     }
   }
 }
} 
{
  "hits": {
    "hits": [
      {
        "_index": "products",
        "_id": "4",
        "_score": 1,
        "_source": {
          "department": "women",
          "brand": "Levi's",
          "description": "jeans",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 75
        }
      },
      {
        "_index": "products",
        "_id": "5",
        "_score": 1,
        "_source": {
          "department": "women",
          "brand": "Levi's",
          "description": "luxury jeans",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 150
        }
      },
      {
        "_index": "products",
        "_id": "7",
        "_score": 1,
        "_source": {
          "department": "women",
          "brand": "Levi's",
          "description": "jeans 2023",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 150
        }
      }
    ]
  }
}

kNN 查询比 kNN collapsing 和聚合搜索可以获得更多样化的结果。 对于下面的 kNN 查询,我们在每个分片上执行 kNN 搜索以获得 10 个最近邻居,然后将其传递到 collapsing 以获取 3 个顶部结果。 因此,我们将在响应中得到 3 个不同的点击。

GET products/_search?filter_path=**.hits
{
 "size" : 3,
 "query": {
   "knn": {
     "field": "embedding",
     "query_vector": [2,2,2,0],
     "num_candidates": 10,
     "filter" : {
       "term" : {
         "department" : "women"
       }
     }
   }
 },
 "collapse": {
   "field": "brand"        
 }
}
{
  "hits": {
    "hits": [
      {
        "_index": "products",
        "_id": "4",
        "_score": 1,
        "_source": {
          "department": "women",
          "brand": "Levi's",
          "description": "jeans",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 75
        },
        "fields": {
          "brand": [
            "Levi's"
          ]
        }
      },
      {
        "_index": "products",
        "_id": "2",
        "_score": 0.2,
        "_source": {
          "department": "women",
          "brand": "Calvin Klein",
          "description": "high-rise beautiful jeans",
          "embedding": [
            1,
            1,
            1,
            1
          ],
          "price": 250
        },
        "fields": {
          "brand": [
            "Calvin Klein"
          ]
        }
      },
      {
        "_index": "products",
        "_id": "3",
        "_score": 0.2,
        "_source": {
          "department": "women",
          "brand": "Gap",
          "description": "every day jeans",
          "embedding": [
            1,
            1,
            1,
            1
          ],
          "price": 50
        },
        "fields": {
          "brand": [
            "Gap"
          ]
        }
      }
    ]
  }
}

顶层 kNN 搜索首先在 DFS 阶段获取全局前 3 个结果,然后在查询阶段将它们传递到 collapse。 我们在响应中只会得到 1 个命中,因为全球 3 个最近的邻居恰好都来自同一品牌。

与聚合类似,kNN query 允许我们获得 3 个不同的存储桶,而 kNN search 仅允许 1 个。

GET products/_search?filter_path=aggregations
{
"size": 0,
"query": {
   "knn": {
     "field": "embedding",
     "query_vector": [2,2,2,0],
     "num_candidates": 10,
     "filter" : {
       "term" : {
         "department" : "women"
       }
     }
   }
 },
 "aggs": {
   "brands": {
     "terms": {
       "field": "brand"
     }
   }
 }
}
{
  "aggregations": {
    "brands": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "Levi's",
          "doc_count": 4
        },
        {
          "key": "Calvin Klein",
          "doc_count": 1
        },
        {
          "key": "Gap",
          "doc_count": 1
        }
      ]
    }
  }
}

而顶层的 search 是这样的:

GET products/_search?filter_path=aggregations
{
  "size": 0,
  "knn": {
    "field": "embedding",
    "query_vector": [
      2,
      2,
      2,
      0
    ],
    "k": 3,
    "num_candidates": 10,
    "filter": {
      "term": {
        "department": "women"
      }
    }
  },
  "aggs": {
    "brands": {
      "terms": {
        "field": "brand"
      }
    }
  }
}
{
  "aggregations": {
    "brands": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "Levi's",
          "doc_count": 3
        }
      ]
    }
  }
}

现在,让我们看一下其他示例,展示 kNN 查询的灵活性。 具体来说,它如何能够灵活地与其他查询结合起来。

kNN 可以是 boolean 查询的一部分(需要注意的是,所有外部查询过滤器都用作 kNN 搜索的后过滤器)。 我们可以使用 kNN 查询的 _name 参数来通过额外信息来增强结果,这些信息告诉 kNN 查询是否匹配及其分数贡献。

GET products/_search?include_named_queries_score
{
 "size": 3,
 "query": {
   "bool": {
     "should": [
       {
         "knn": {
           "field": "embedding",
           "query_vector": [2,2,2,0],
           "num_candidates": 10,
           "_name": "knn_query"
         }
       },
       {
         "match": {
           "description": {
             "query": "luxury",
             "_name": "bm25query"
           }
         }
       }
     ]
   }
 }
}
{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 7,
      "relation": "eq"
    },
    "max_score": 2.8042283,
    "hits": [
      {
        "_index": "products",
        "_id": "5",
        "_score": 2.8042283,
        "_source": {
          "department": "women",
          "brand": "Levi's",
          "description": "luxury jeans",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 150
        },
        "matched_queries": {
          "knn_query": 1,
          "bm25query": 1.8042282
        }
      },
      {
        "_index": "products",
        "_id": "4",
        "_score": 1,
        "_source": {
          "department": "women",
          "brand": "Levi's",
          "description": "jeans",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 75
        },
        "matched_queries": {
          "knn_query": 1
        }
      },
      {
        "_index": "products",
        "_id": "6",
        "_score": 1,
        "_source": {
          "department": "men",
          "brand": "Levi's",
          "description": "jeans",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 50
        },
        "matched_queries": {
          "knn_query": 1
        }
      }
    ]
  }
}

kNN 也可以是复杂查询的一部分,例如 pinned 查询。 当我们想要显示最接近的结果,但又想要提升选定数量的其他结果时,这非常有用。

GET products/_search
{
 "size": 3,
 "query": {
   "pinned": {
     "ids": [ "1", "2" ],
     "organic": {
       "knn": {
           "field": "embedding",
           "query_vector": [2,2,2,0],
           "num_candidates": 10,
           "_name": "knn_query"
         }
     }
   }
 }
}
{
  "took": 9,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 7,
      "relation": "eq"
    },
    "max_score": 1.7014124e+38,
    "hits": [
      {
        "_index": "products",
        "_id": "1",
        "_score": 1.7014124e+38,
        "_source": {
          "department": "women",
          "brand": "Levi's",
          "description": "high-rise red jeans",
          "embedding": [
            1,
            1,
            1,
            1
          ],
          "price": 100
        },
        "matched_queries": [
          "knn_query"
        ]
      },
      {
        "_index": "products",
        "_id": "2",
        "_score": 1.7014122e+38,
        "_source": {
          "department": "women",
          "brand": "Calvin Klein",
          "description": "high-rise beautiful jeans",
          "embedding": [
            1,
            1,
            1,
            1
          ],
          "price": 250
        },
        "matched_queries": [
          "knn_query"
        ]
      },
      {
        "_index": "products",
        "_id": "4",
        "_score": 1,
        "_source": {
          "department": "women",
          "brand": "Levi's",
          "description": "jeans",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 75
        },
        "matched_queries": [
          "knn_query"
        ]
      }
    ]
  }
}

我们甚至可以将 kNN 查询作为 function_score 查询的一部分。 当我们需要为 kNN 查询返回的结果定义自定义分数时,这非常有用:​

GET products/_search
{
 "size": 3,
 "query": {
   "function_score": {
     "query": {
       "knn": {
           "field": "embedding",
           "query_vector": [2,2,2,0],
           "num_candidates": 10,
           "_name": "knn_query"
         }
     },
     "functions": [
       {
         "filter": { "match": { "department": "men" } },
         "weight": 100
       },
       {
         "filter": { "match": { "department": "women" } },
         "weight": 50
       }
     ]
   }
 }
}
{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 7,
      "relation": "eq"
    },
    "max_score": 100,
    "hits": [
      {
        "_index": "products",
        "_id": "6",
        "_score": 100,
        "_source": {
          "department": "men",
          "brand": "Levi's",
          "description": "jeans",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 50
        },
        "matched_queries": [
          "knn_query"
        ]
      },
      {
        "_index": "products",
        "_id": "4",
        "_score": 50,
        "_source": {
          "department": "women",
          "brand": "Levi's",
          "description": "jeans",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 75
        },
        "matched_queries": [
          "knn_query"
        ]
      },
      {
        "_index": "products",
        "_id": "5",
        "_score": 50,
        "_source": {
          "department": "women",
          "brand": "Levi's",
          "description": "luxury jeans",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 150
        },
        "matched_queries": [
          "knn_query"
        ]
      }
    ]
  }
}

当我们想要组合 kNN 搜索和其他查询的结果时,kNN 查询作为 dis_max 查询的一部分非常有用,以便文档的分数来自排名最高的子句,并为任何其他子句提供打破平局的增量。

GET products/_search
{
 "size": 5,
 "query": {
   "dis_max": {
     "queries": [
       {
         "knn": {
           "field": "embedding",
           "query_vector": [2,2, 2,0],
           "num_candidates": 3,
           "_name": "knn_query"
         }
       },
       {
         "match": {
           "description": "high-rise jeans"
         }
       }
     ],
     "tie_breaker": 0.8
   }
 }
}
{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 7,
      "relation": "eq"
    },
    "max_score": 1.890432,
    "hits": [
      {
        "_index": "products",
        "_id": "1",
        "_score": 1.890432,
        "_source": {
          "department": "women",
          "brand": "Levi's",
          "description": "high-rise red jeans",
          "embedding": [
            1,
            1,
            1,
            1
          ],
          "price": 100
        }
      },
      {
        "_index": "products",
        "_id": "2",
        "_score": 1.890432,
        "_source": {
          "department": "women",
          "brand": "Calvin Klein",
          "description": "high-rise beautiful jeans",
          "embedding": [
            1,
            1,
            1,
            1
          ],
          "price": 250
        }
      },
      {
        "_index": "products",
        "_id": "4",
        "_score": 1.0679927,
        "_source": {
          "department": "women",
          "brand": "Levi's",
          "description": "jeans",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 75
        },
        "matched_queries": [
          "knn_query"
        ]
      },
      {
        "_index": "products",
        "_id": "6",
        "_score": 1.0679927,
        "_source": {
          "department": "men",
          "brand": "Levi's",
          "description": "jeans",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 50
        },
        "matched_queries": [
          "knn_query"
        ]
      },
      {
        "_index": "products",
        "_id": "5",
        "_score": 1.0556482,
        "_source": {
          "department": "women",
          "brand": "Levi's",
          "description": "luxury jeans",
          "embedding": [
            2,
            2,
            2,
            0
          ],
          "price": 150
        },
        "matched_queries": [
          "knn_query"
        ]
      }
    ]
  }
}

kNN 搜索作为查询已在 8.12 版本中引入。 请尝试一下,如果有任何反馈,我们将不胜感激。

原文:Introducing kNN query, an expert way to do kNN search — Elastic Search Labs

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【学习】focal loss 损失函数

focal loss用于解决正负样本的不均衡情况 通常我们需要预测的正样本要少于负样本,正负样本分布不均衡会带来什么影响?主要是两个方面。 样本不均衡的话,训练是低效不充分的。因为困难的正样本数量较少,大部分时间都在学习没有用…

【linux】 查看 Linux 重启历史记录(reboot)

了解 Linux 重启日志 /var/log 目录隐藏着 Linux 日志机制的核心信息,它是记录系统活动的宝贵仓库。然而,仅仅有日志还不够,真正的难题在于,如何从大量数据中提炼出与系统重启相关的关键信息。 在 /var/log 目录中,可…

更改wpf原始默认按钮的样式

样式 代码 <Window x:Class"WpfApp4.Window1"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/2008…

机械臂雅可比矩阵的矢量积理解和matlab实现

雅可比矩阵的第Ji列&#xff1a; 关于一些基本概念可以参考博客&#xff0c;部分细节如下&#xff1a; 每个移动关节&#xff0c;Ji可以这样计算&#xff1a; 每个旋转关节&#xff0c;Ji这样计算&#xff1a; 有时候要求按照末端执行器坐标系{n}来执行一些位移旋转之类的…

【QT+QGIS跨平台编译】之六:【LZMA+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、lzma介绍二、文件下载三、文件分析四、pro文件五、编译实践 一、lzma介绍 LZMA&#xff08;Lempel-Ziv-Markov chain-Algorithm的缩写&#xff09;&#xff0c;是一个Deflate和LZ77算法改良和优化后的压缩算法。 libLzma是基于LZMA压缩算法封装的开源库。2001年被…

如何用AirServer进行手机投屏?,Airserver 永久激活注册码

AirServer一款投屏神器&#xff0c;可以帮你轻松地将iPhone、iPad投屏到Mac。是不是经常看到游戏主播用AirServer投屏&#xff1f;此外&#xff0c;AirServer也是视频Up主必备工具之一&#xff01;用来录制演示教程不错。除了实现单个手机投屏到电脑或荧幕。如果你有多画面投屏…

界面控件DevExpress ASP.NET Data Grid组件 - 可快速处理各类型数据!(一)

由DevExpress开发的快速且功能完整的ASP.NET Web Forms的Data Grid组件&#xff0c;从全面的数据塑造和数据过滤选项到十多个集成数据编辑器&#xff0c;该套件提供了帮助用户构建极佳数据所需的一些&#xff0c;没有限制&#xff01; P.S&#xff1a;DevExpress ASP.NET Web …

R303 指纹识别模块功能实现流程

1 基本通信流程 1.1 UART 命令包的处理过程 1.2 UART 数据包的发送过程 UART 传输数据包前&#xff0c;首先要接收到传输数据包的指令包&#xff0c;做好传输准备后发送成功应答包&#xff0c;最后才开始传输数据包。数据包主要包括&#xff1a;包头、设备地址、包标识、包长…

表单的总数据为什么可以写成一个空对象,不用具体的写表单中绑定的值,vue3

<el-form :model"form" label-width"120px"><el-form-item label"Activity name"><el-input v-model"form.name" /></el-form-item> </el-form> const form ref({})from为空对象 在v-model里写form…

最新数据传输安全难点解决方案(上)

在数据量激增和网络环境日益复杂的背景下&#xff0c;确保数据在传输过程中的安全性、效率和可靠性&#xff0c;已成为众多企业亟需解决的问题。镭速小编将带大家探讨数据传输安全所面临的主要挑战&#xff0c;并介绍一些前沿的数据传输安全技术和策略&#xff0c;以供企业参考…

RK3568笔记十一:mpp编解码

若该文为原创文章&#xff0c;转载请注明原文出处。 主要是想测试MPP的解码&#xff0c;为后续做测试。 一、环境 1、平台&#xff1a;rk3568 2、开发板:ATK-RK3568正点原子板子 3、环境&#xff1a;buildroot 二、编译 使用的是正点原子提供的虚拟机&#xff0c;搭建好环…

【cucumber】cucumber-reporting生成测试报告

原始的cucumber report 比较粗糙 我们可以通过cucumber-reporting 插件对报告进去优化 在pom.xml里面添加cuccumber-reporting 插件 <!-- 根据 cucumber json文件 美化测试报告--><dependency><groupId>net.masterthought</groupId><artifactId>…

【博士每天一篇论文-综述】Deep Echo State Network (DeepESN)_ A Brief Survey

阅读时间&#xff1a;2023-11-22 1 介绍 年份&#xff1a;2017 作者&#xff1a;C. Gallicchio 比萨大学计算机科学系终身教授助理教授&#xff0c;A. Micheli&#xff0c;比萨大学计算机科学系 期刊&#xff1a; ArXiv 引用量&#xff1a;68 这是两个大牛的论文&#xff0c;…

charles mac抓包unknown问题

第一步&#xff1a;mac上安装Charles后&#xff0c;mac安装证书&#xff1a; 第二步&#xff1a;mac上信任证书 第三步&#xff1a;手机上安装证书 安装提示&#xff1a;电脑上通过help–>SSLProxying–> Install Charles Root Ceriticate on a Mobile Device or Remote …

hadoop必记知识点(2)

6. hadoop集群计算的时候&#xff0c;什么是集群的主要瓶颈&#xff1f;展开说一下&#xff0c;生产遇到了什么问题&#xff1f; 在 Hadoop 集群进行计算时&#xff0c;可能会遇到多个瓶颈&#xff0c;但最主要的通常包括网络带宽、存储以及 CPU 处理能力。 网络带宽&#xf…

如何制作自己的实景中国视频地图?

让每一个人都有自己的地图&#xff01; 我们在《水经微图Web版1.5.0发布》一文中&#xff0c;提到了水经微图&#xff08;简称“微图”&#xff09;Web版新增了视频气泡的功能。 现在&#xff0c;我们为你分享一下如何基于此功能&#xff0c;制作一个属于自己的实景中国视频地…

Axios取消请求:AbortController

AbortController AbortController() 构造函数创建了一个新的 AbortController 实例。MDN官网给出了一个利用AbortController取消下载视频的例子。 核心逻辑是&#xff1a;利用AbortController接口的只读属性signal标记fetch请求&#xff1b;然后在需要取消请求的时候&#xff0…

【XR806开发板试用】系列之一 - Linux环境下Ubuntu完全开发流程

前言 为了让极术社区开发者体验搭载安谋科技STAR-MC1处理器的面向IoT领域的全志XR806开发板&#xff0c;极术社区联合全志在线开发者社区共同推出XR806开发板免费试用活动。 极术社区特准备了200块XR806开发板作为2022年社区新年活动&#xff0c;申请的人数有600多&#xff0c…

分布式websocket IM聊天系统相关问题问答【第九期】

前言 上期视频讲解了自己关于聊天系统的设计的时候出现了一些不一样的声音。不了解情况的可以看上上期视频。这期主要是讨论。IM聊天系统设计方案多。我的先说明一下自己的技术背景互相之间才能更好的理解。 本期对应视频 目前已经写的文章有。并且有对应视频版本。 git项目地…

线性代数的学习和整理23:用EXCEL和python 计算向量/矩阵的:内积/点积,外积/叉积

目录 1 乘法 1.1 标量乘法(中小学乘法) 1.1.1 乘法的定义 1.1.2 乘法符合的规律 1.2 向量乘法 1.2.1 向量&#xff1a;有方向和大小的对象 1.2.2 向量的标量乘法 1.2.3 常见的向量乘法及结果 1.2.4 向量的其他乘法及结果 1.2.5 向量的模长&#xff08;长度&#xff0…