Neo4j v5 中 Cypher 的变化

How Cypher changed in Neo4j v5

Neo4j v5 中 Cypher 的变化

几周前,Neo4j 5 发布了。如果你像我一样,在 Neo4j 4 的后期版本中忽略了所有的弃用警告,你可能需要更新你的 Cypher 查询以适应最新版本的 Neo4j。幸运的是,新的 Cypher 语法没有显著差异,所以更新过程应该不会太困难。然而,我决定写这篇博客文章来帮助你过渡。此外,我还将介绍一些新的 Cypher 语法,这些语法可以简化你的查询。
Jupyter Notebook on GitHub.
这篇博客文章中的 Cypher 示例可以在 GitHub 上的 Jupyter Notebook 中找到。

Neo4j 环境搭建

为了跟随本篇文章中的代码示例,您需要搭建一个 Neo4j 环境。像往常一样,您可以使用 Neo4j 桌面应用程序来搭建一个本地环境。另一方面,您可以使用作为 Neo4j Aura 提供的免费云实例。如果您选择 Neo4j Aura 路线,使用永久免费的实例并启动一个不带有预填充图的空白项目。_
附言:永久免费的 Neo4j Aura 实例不提供 GDS 支持。_

Dataset 数据集

我找到了一个描述《沙丘》系列中角色的数据集。
Frank Herbert’s DUNE Characters弗兰克·赫伯特的《沙丘》角色Social networks in a fantastic world… help build the dataset!一个奇妙世界中的社交网络……帮助构建数据集!www.kaggle.com网址:www.kaggle.com

Dune 数据集在 Kaggle 上可用,为了让您更方便,我已经将数据集复制到一个 GitHub 仓库,这样您就不必下载数据集,可以轻松地在您的本地或云实例的 Neo4j 中导入它。此外,我已经将关系类型“父母-子女”和“其他家庭成员”重命名为“家庭成员”,并移除了“未知”关系。

Graph Model 图模型

image.png
Dune graph model. Image by the author.
沙丘图模型。图片由作者提供。

图模型围绕角色展开。角色节点具有多个属性,如名称、文化,以及他们的出生或死亡时间。此外,他们对家族的忠诚度被表示为次要节点标签。使用次要节点标签而不是单独的节点的主要原因是为了展示 Cypher 中的新节点标签过滤选项。角色之间有四种类型的关系:

  • ALLIES 盟友
  • ENEMIES, 敌人,
  • FAMILY 家庭
  • MARRIAGE 婚姻

Dataset import 数据集导入

As with most imports, you first want to define unique constraints in Neo4j. Unique constraints ensure that a given property is unique for every node with a particular label.
与大多数导入操作一样,您首先希望在 Neo4j 中定义唯一性约束。唯一性约束确保对于具有特定标签的每个节点,给定属性是唯一的。
The syntax for defining unique constraints has slightly changed in Neo4j v5.
在 Neo4j v5 中,定义唯一性约束的语法略有变化。
image.png
Syntax change for UNIQUE CONSTRAINTS. Image by the author.
唯一约束的语法变更。图片由作者提供。
The new syntax for unique constraints has two keywords replaced. The ON keyword is replaced with FOR, while the ASSERT is changed to REQUIRE.
新的唯一约束语法有两个关键字被替换。ON 关键字被替换为 FOR,而 ASSERT 被更改为 REQUIRE。
The following Cypher statements define the unique constraint for name property of Character nodes.
以下 Cypher 语句为角色节点的名称属性定义了唯一约束。
CREATE CONSTRAINT IF NOT EXISTS FOR (c:Character) REQUIRE c.name IS UNIQUE;
Next, you need to import the CSV file. Even though the Dune CSV file has only 1000 rows, you will pretend you are dealing with a large CSV file with many thousands of rows. Therefore, you want to use batch import into multiple transactions. As USING PERIODIC COMMIT clause has been deprecated in Neo4j v5, you need to use the new batched transaction syntax.
接下来,你需要导入 CSV 文件。尽管 Dune CSV 文件只有 1000 行,但你会假装你正在处理一个包含数千行的大型 CSV 文件。因此,你想要使用批量导入到多个事务中。由于 USING PERIODIC COMMIT 子句已在 Neo4j v5 中被弃用,你需要使用新的批量事务语法。
image.png
Syntax change for importing large CSV files. Image by the author.
导入大型 CSV 文件的语法变更。图片由作者提供。
The subqueries were already introduced in Neo4j v4 but have taken on a more prominent role in v5. The subqueries are instantiated with a CALL clause and wrapped with curly brackets {}. They are great for various functionalities like post-union processing, limiting results per row, and conditional execution. Additionally, the Cypher subqueries are now the only native Cypher syntax (excluding APOC) to batch a single Cypher statement into multiple transactions. In order to specify that the Cypher subquery should be split into multiple transactions, you need to add IN TRANSACTIONS OF x ROWS, where the x represents the number of rows for each batch.
子查询在 Neo4j v4 中已经引入,但在 v5 中扮演了更重要的角色。子查询使用 CALL 子句实例化,并用花括号 {} 包裹。它们非常适合各种功能,如联合后处理、限制每行的结果以及条件执行。此外,Cypher 子查询现在是唯一的原生 Cypher 语法(不包括 APOC)将单个 Cypher 语句拆分为多个事务。为了指定 Cypher 子查询应该拆分为多个事务,你需要添加 IN TRANSACTIONS OF x ROWS,其中 x 表示每个批次的行数。
The following Cypher statement contains two nested subqueries. The top-level subquery is used to batch the import into a new transaction for every 10 rows. On the other hand, you use the nested Cypher subquery as a conditional execution feature.
下面的 Cypher 语句包含两个嵌套子查询。顶级子查询用于将导入批处理到每 10 行的新事务中。另一方面,您使用嵌套的 Cypher 子查询作为条件执行特性。

LOAD CSV WITH HEADERS FROM "https://bit.ly/3kbU21V" AS row
CALL {
  WITH row // Explicit import of variables
  MERGE (c:Character {name:row.Character})
  SET c += apoc.map.clean(row, 
     ["name", "Detail", "to", "relationship_type", "House_Allegiance"], [])
  WITH c, row
  CALL apoc.create.addLabels(c, [row.House_Allegiance]) YIELD node
  // nested subquery for conditional execution
  CALL {
    WITH row, c // Explicit import of variables
    WITH row, c
    WHERE row.to IS NOT NULL
    MERGE (c1:Character {name: row.to})
    WITH row, c, c1
    CALL apoc.merge.relationship(c, toUpper(row.relationship_type), {}, {}, c1)
    YIELD rel
    RETURN count(*) AS count
  }
  RETURN count(*) AS finalCount
} IN TRANSACTIONS OF 10 ROWS // Define batched transaction for every 10 rows
RETURN count(*)

The import query is a bit more complicated because I wanted to do the import in a single Cypher statement. It starts with the LOAD CSV clause that you might have seen before. In order to batch the import into multiple transactions, you need to initiate a Cypher subquery with the CALL clause. The top-level subquery ends with the IN TRANSACTIONS OF x ROWS clause, which specifies the transaction batching.
导入查询有点复杂,因为我想用单个 Cypher 语句完成导入。它以您可能之前见过的 LOAD CSV 子句开始。为了将导入分批到多个事务中,您需要使用 CALL 子句启动一个 Cypher 子查询。顶级子查询以 IN TRANSACTIONS OF x ROWS 子句结束,该子句指定了事务批处理。
If you want to use any variable in the Cypher statement, you must explicitly import it with the WITH clause. First, the top-level subquery import the row variable from the outer query. Next, it merges the Character node and sets a couple of properties. Since adding dynamic secondary labels is not supported in plain Cypher, you can use the APOC’s procedure.
如果您想在使用 Cypher 语句中的任何变量,您必须使用 WITH 子句明确导入它。首先,顶级子查询从外部查询导入行变量。接下来,它合并了角色节点并设置了一些属性。由于在普通 Cypher 中不支持添加动态二级标签,您可以使用 APOC 的过程。
Some of the Dune characters have additional relationships defined in the to and relationship_type columns of the CSV. On the other hand, the to and relationship_type columns are empty for several rows. The FOREACH conditional execution trick was my go-to option for the better part of my blog post. However, as the theme of this blog post are Cypher subqueries, I have decided to show you how to use Cypher subqueries for conditional execution. First, with the nested Cypher subquery, you need to import both the row and the c variables. Next, you need to filter out only rows where the to column is not null. However, you cannot filter variables in the same WITH clause used to import them. Therefore, you need to add a second WITH clause to filter rows. Lastly, you use the APOC’s procedure for merging relationships, as the plain Cypher syntax does not support creating properties with dynamic relationship types.
一些《沙丘》中的角色在 CSV 文件的 to 和 relationship_type 列中定义了额外的关系。另一方面,有几行的 to 和 relationship_type 列是空的。FOREACH 条件执行技巧是我博客文章的大部分内容的首选解决方案。然而,由于这篇博客文章的主题是 Cypher 子查询,我决定向您展示如何使用 Cypher 子查询进行条件执行。首先,使用嵌套的 Cypher 子查询,您需要导入 row 和 c 变量。接下来,您需要过滤出 to 列不为空的行。但是,您不能在用于导入它们的同一 WITH 子句中过滤变量。因此,您需要添加第二个 WITH 子句来过滤行。最后,使用 APOC 的过程来合并关系,因为普通的 Cypher 语法不支持创建具有动态关系类型的属性。
You can check out the documentation if this example was a bit too packed for you.
如果这个例子对你来说有点过于复杂,你可以查看文档。

New inline filtering options

新的内联过滤选项
There are many new options available for inline filtering in Neo4j v5. So what exactly is inline filtering? Essentially, it is the ability to filter a graph pattern directly in the MATCH clause.
Neo4j v5 中有许多新的内联过滤选项可用。那么究竟什么是内联过滤呢?本质上,它就是直接在 MATCH 子句中过滤图模式的能力。
You will begin by learning the new syntax for filtering node labels. In Neo4j v5, the following logical expressions were introduced to allow more flexible node filtering.
你将首先学习过滤节点标签的新语法。在 Neo4j v5 中,引入了以下逻辑表达式,以允许更灵活的节点过滤。

  • & — AND expression & — 与表达式
  • | — OR expression — 或运算表达式
  • ! — NOT expression — 非运算表达式

For example, if you want to match all nodes with either the Fremen or Harkonnen label, you can use the | expression.
例如,如果你想匹配所有带有 Fremen 或 Harkonnen 标签的节点,你可以使用|运算表达式。

MATCH (c:Fremen|Harkonnen)
RETURN count(*)

On the other hand, if you need to find all nodes with both the Character and Harkonnen labels, you can use the & expression.
另一方面,如果你需要找到同时具有 Character 和 Harkonnen 标签的所有节点,你可以使用 & 表达式。

MATCH (c:Character&Harkonnen)
RETURN count(*)

The ! expression allows you to negate node labels. For example, say that you want to match all nodes with the Character label but don’t have the Harkonnen label.
! 表达式允许你否定节点标签。例如,假设你想要匹配所有具有 Character 标签但不具有 Harkonnen 标签的节点。

MATCH (c:Character&!Harkonnen)
RETURN count(*)

The Cypher now also supports nested expressions for filtering node labels. For example, the following Cypher statement matches all nodes that don’t have the Fremen or the Harkonnen labels.
Cypher 现在还支持用于过滤节点标签的嵌套表达式。例如,以下 Cypher 语句匹配所有没有 Fremen 或 Harkonnen 标签的节点。

MATCH (c:!(Fremen|Harkonnen))
RETURN count(*)

The expressions are nested using the parenthesis ().
表达式使用括号()进行嵌套。
Another feature added to Cypher is the option to include the WHERE clause within the MATCH clause. This allows you to apply all the flexibility of the Cypher filtering by node properties directly within the MATCH statement.
Cypher 增加的另一个特性是在 MATCH 子句中包含 WHERE 子句的选项。这允许您在 MATCH 语句中直接应用所有基于节点属性的 Cypher 过滤的灵活性。
For example, the following Cypher statement matches all characters where the Culture property starts with Z and the Died property is not null.
例如,以下 Cypher 语句匹配所有 Culture 属性以 Z 开头且 Died 属性不为空的角色。

MATCH (c:Character WHERE c.Culture STARTS WITH "Z" AND c.Died IS NOT NULL)
RETURN c.name AS character

The same logical expressions used to filter nodes can also be used when filtering relationship types. For example, the | expression, which expresses the logical OR, has been in Cypher for quite some time.
用于过滤节点的相同逻辑表达式也可用于过滤关系类型。例如,表示逻辑“或”的 | 表达式已经在 Cypher 中存在一段时间了。
The following Cypher statement matches all Character nodes with the Culture property values of Bene Gesserit and expands their ALLIES or FAMILY relationships.
以下 Cypher 语句匹配所有具有 Culture 属性值为 Bene Gesserit 的 Character 节点,并扩展他们的 ALLIES 或 FAMILY 关系。

MATCH p=(c:Character WHERE c.Culture = "Bene Gesserit")-[r:ALLIES|FAMILY]-()
RETURN [n in nodes(p) | n.name] AS pairs, type(r) AS results

Using only the & expression does not really make sense as a single relationship cannot have more than one type. However, the combined with the negation ! expression the & can come in handy.
仅使用 & 表达式实际上没有太大意义,因为单个关系不能有超过一种类型。然而,结合否定 ! 表达式,& 可以派上用场。
For example, the following Cypher statement expands all relationships that are not ALLIES or FAMILY.
例如,以下 Cypher 语句扩展了所有不是 ALLIES 或 FAMILY 的关系。

MATCH p=(c:Character WHERE c.Culture = "Fremen")-[r:!ALLIES&!FAMILY]-()
RETURN [n in nodes(p) | n.name] AS pairs, type(r) AS results

Existential subqueries 存在量子查询

Next, you will learn how the syntax for existential subqueries changed. An existential subquery can be used to find graph patterns that are part of a specified pattern.
接下来,你将学习存在量子查询的语法是如何变化的。存在量子查询可以用来找到作为指定模式一部分的图模式。
image.png
Syntax change for existential filters. Image by the author.
存在性过滤器的语法变更。图片由作者提供。
In this example, the existential subquery is used to find Character nodes that have either incoming or outgoing FAMILY relationships. I am a fan of existential subqueries as they offer the flexibility to filter nodes based on any graph patterns without having to expand them in the MATCH clause and worry about query cardinality (number of rows). In Neo4j v5, you have to add the EXISTS clause and wrap the specified graph pattern used for filtering with curly brackets in order to execute existential subqueries.
在这个例子中,使用存在性子查询来查找具有进入或离开 FAMILY 关系的角色节点。我是存在性子查询的粉丝,因为它们提供了基于任何图模式过滤节点的灵活性,而无需在 MATCH 子句中展开它们,并担心查询基数(行数)。在 Neo4j v5 中,您必须添加 EXISTS 子句,并用花括号括起用于过滤的指定图模式,才能执行存在性子查询。

MATCH (c:Character)
WHERE exists { (c)-[:FAMILY]-() }
RETURN count(*) AS count

Additionally, you can now introduce new reference variables in the existential subqueries. For example, the following existential subquery filters Character nodes with a FAMILY relationship. However, only the patterns where the end node of the FAMILY relationship has both the ALLIES and the MARRIAGE relationship are considered.
此外,您现在可以在存在性子查询中引入新的引用变量。例如,以下存在性子查询过滤具有 FAMILY 关系的角色节点。然而,只有在 FAMILY 关系的结束节点同时具有 ALLIES 和 MARRIAGE 关系的模式才被考虑。

MATCH (c:Character)
WHERE exists { (c)-[:FAMILY]-(t)
               WHERE (t)-[:ALLIES]-() AND (t)-[:MARRIAGE]-() }
RETURN count(*) AS count

You may also see examples of a MATCH clause used within the existential subquery. Based on my experience, the MATCH clause is entirely optional. However, it might make the existential subquery syntax more readable and intuitive.
您还可以看到在存在子查询中使用 MATCH 子句的示例。根据我的经验,MATCH 子句完全是可选的。然而,它可能使存在子查询的语法更易于阅读和直观。

MATCH (c:Character)
WHERE exists { MATCH (c)-[:FAMILY]-(t)
               WHERE (t)-[:ALLIES]-() AND (t)-[:MARRIAGE]-() }
RETURN count(*) AS count

Check out the documentation for more examples of existential subqueries.
查看文档以获取更多存在子查询的示例。

Count subqueries 计数子查询

The last category of subqueries in this post is the so-called count subqueries. They are used to count the number of defined graph patterns. For example, I frequently used them in my previous blog posts to count the number of relationships a node has.
本帖子中子查询的最后一个类别是所谓的计数子查询。它们用于计算已定义图形模式的数量。例如,我经常在我以前的博客文章中使用它们来计算一个节点有多少关系。
image.png
Syntax change for counting subqueries. Image by the author.
计数子查询的语法变更。图片由作者提供。
Previously, you could wrap a graph pattern with the size() in order to count the number of particular patterns. It is a handy syntax to count graph patterns without affecting the cardinality of the main query. Additionally, it might outperform other approaches to counting the number of relationships. In Neo4j v5, you need to replace the size() operator with the count{}.
以前,你可以用 size() 包装一个图形模式来计算特定模式的数量。这是一种方便的语法,可以在不影响主查询基数的情况下计算图形模式的数量。此外,它可能比其他计算关系数量的方法性能更好。在 Neo4j v5 中,你需要用 count{} 替换 size() 操作符。
The following Cypher statement returns the top five Character node ordered by their degree (relationship count).
下面的 Cypher 语句按照它们的度数(关系计数)返回前五个角色节点。

MATCH (c:Character)
RETURN c.name AS character,
       count{ (c)--() } AS degree
ORDER BY degree DESC
LIMIT 5

As before, you can filter nodes by using the counting subqueries in a WHERE clause. In this example, the Cypher statement filters nodes with more than relationships.
如同之前,你可以使用 WHERE 子句中的计数子查询来过滤节点。在这个例子中,Cypher 语句过滤了具有多于某个数量关系节点。

MATCH (c:Character)
WHERE count{ (c)--() } > 2
RETURN count(*) AS count

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

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

相关文章

【翻译】REST API

自动伸缩 API 创建或更新自动伸缩策略 API 此特性设计用于 Elasticsearch Service、Elastic Cloud Enterprise 和 Kubernetes 上的 Elastic Cloud 的间接使用。不支持直接用户使用。 创建或更新一个自动伸缩策略。 请求 PUT /_autoscaling/policy/<name> {"rol…

什么是UDP反射放大攻击,有什么安全措施可以防护UDP攻击

随着互联网的飞速发展和业务复杂性的提升&#xff0c;网络安全问题日益凸显&#xff0c;其中分布式拒绝服务&#xff08;DDoS&#xff09;攻击成为危害最为严重的一类网络威胁之一。 近些年&#xff0c;网络攻击越来越频繁&#xff0c;常见的网络攻击类型包括&#xff1a;蠕虫…

AI图书推荐:用ChatGPT快速创建在线课程

您是否是您领域的专家&#xff0c;拥有丰富的知识和技能可以分享&#xff1f;您是否曾想过创建一个在线课程&#xff0c;但被这个过程吓倒了&#xff1f;那么&#xff0c;是时候把这些担忧放在一边&#xff0c;迈出这一步了&#xff01;有了这本指南和ChatGPT的帮助&#xff0c…

ssh远程访问windows系统下的jupyterlab

网上配置这一堆那一堆&#xff0c;特别乱&#xff0c;找了好久整理后发在这里 由于既想打游戏又想做深度学习&#xff0c;不舍得显卡性能白白消耗&#xff0c;这里尝试使用笔记本连接主机 OpenSSH 最初是为 Linux 系统开发的&#xff0c;现在也支持包括 Windows 和 macOS 在内…

[1673]jsp在线考试管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 在线考试管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&…

R语言学习—4—数据矩阵及R表示

1、创建向量、矩阵 在R中&#xff0c;c()函数用于创建向量或组合数据对象。它在某些情况下可能会被省略&#xff0c;因为R有一些隐式的向量创建规则。例如&#xff0c;当你使用:操作符创建一个数字序列时&#xff0c;R会自动创建一个向量&#xff0c;所以你不需要显式地调用c()…

《QT实用小工具·五十二》文本或窗口炫酷有趣的滚动条——果冻条

1、概述 源码放在文章末尾 该项目实现了文本或窗口纤细的滚动条——果冻条 一个可以像弓弦一样拉出来&#xff0c;并且来回弹动的普通滚动条。 思路为此&#xff0c;但发现实际效果更像条状果冻&#xff0c;并且略有谐音&#xff0c; 故&#xff0c;称之为——“果冻条”&am…

条件依赖性的方法示例

5个条件判断一件事情是否发生&#xff0c;每个条件可能性只有2种&#xff08;发生或者不发生&#xff09;&#xff0c;计算每个条件对这件事情发生的影响力&#xff0c;条件之间有很强的依赖关系。 例一 如果条件之间有很强的依赖关系&#xff0c;那么简单地计算每个条件独立的…

初探 Google 云原生的CICD - CloudBuild

大纲 Google Cloud Build 简介 Google Cloud Build&#xff08;谷歌云构建&#xff09;是谷歌云平台&#xff08;Google Cloud Platform&#xff0c;GCP&#xff09;提供的一项服务&#xff0c;可帮助开发人员以一致和自动化的方式构建、测试和部署应用程序或构件。它为构建和…

B树:原理、操作及应用

B树&#xff1a;原理、操作及应用 一、引言二、B树概述1. 定义与性质2. B树与磁盘I/O 三、B树的基本操作1. 搜索&#xff08;B-TREE-SEARCH&#xff09;2. 插入&#xff08;B-TREE-INSERT&#xff09;3. 删除&#xff08;B-TREE-DELETE&#xff09; 四、B树的C代码实现示例五、…

基于 Wireshark 分析 IP 协议

一、IP 协议 IP&#xff08;Internet Protocol&#xff09;协议是一种网络层协议&#xff0c;它用于在计算机网络中实现数据包的传输和路由。 IP协议的主要功能有&#xff1a; 1. 数据报格式&#xff1a;IP协议将待传输的数据分割成一个个数据包&#xff0c;每个数据包包含有…

mac电脑关于ios端的appium真机自动化测试环境搭建

一、app store 下载xcode,需要登录apple id 再开始下载 二、安装homebrew 1、终端输入命令&#xff1a; curl -fsSL <https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh>如果不能直接安装&#xff0c;而是出现了很多内容&#xff0c;那么这个时候不要着急&…

06.Git远程仓库

Git远程仓库 #仓库种类&#xff0c;举例说明 github gitlab gitee #以这个仓库为例子操作登录码云 https://gitee.com/projects/new 创建仓库 选择ssh方式 需要配置ssh公钥 在系统上获取公钥输入命令&#xff1a;ssh-keygen 查看文件&#xff0c;复制公钥信息内…

【画图】读取无人机IMU数据并打印成log用matlab分析

一、修改IMU频率 原来的imu没有加速度信息&#xff0c;查看加速度信息的指令为&#xff1a; rostopic echo /mavros/imu/data 修改imu频率&#xff0c;分别修改的是 原始IMU数据话题 /mavros/imu/data_raw。飞控计算过后的IMU数据 /mavros/imu/data rosrun mavros mavcmd l…

Uniapp好看登录注册页面

个人介绍 hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的…

【Linux-点灯烧录-SD卡/USB烧写】

目录 1. 烧写方式2. 烧写之代码编译2.1 led.s->led.o2.2 led.o->led.elf2.3 led.elf->led.bin2.4 反汇编&#xff1a;led.elf->led.dis 3. 烧写之烧录到SD卡上&#xff1a;3.1 开启烧录软件权限&#xff1a;3.2 确定SD卡的格式&#xff1a;FAT323.3 烧录到SD卡上3.…

makefile中wildcard函数和patsubst用法

makefile中函数用法 makefile中函数的调用语法&#xff1a; $(<function> <arguments>) 或 ${<function> <arguments>}函数调用以$开头用{}或者()将函数名以及参数包含起来函数名和第一个参数之间以空格分隔参数之间使用逗号分隔 wildcard函数 wil…

python判断大图中包含小图并输出位置总结

python判断大图中包含小图并输出位置总结 没啥可说的&#xff0c;项目遇到了就直接上代码&#xff0c;可以减轻劳动力&#xff0c;花最少得时间实现应用功能。 import cv2 # 读取大图片和小图片的路径 img_big cv2.imread(big_image.png) img_small cv2.imread(small_image…

VScode+ubuntu配置ROS开发环境

VScodeubuntu配置ROS开发环境 写在前面 在vscode中先安装几个插件&#xff1a;中文语言包、Python插件、C插件、CMake插件、vscode-icons、ROS插件、Visual Studio IntelliCode、URDF、Markdown All in One 一、工作空间是什么 在ROS机器人开发中&#xff0c;我们针对机器人…

ue引擎游戏开发笔记(27)——解决角色移动及转动存在卡顿掉帧小技巧

1.需求分析&#xff1a; 随之游戏越来越大&#xff0c;难免出现部分时候移动出现卡顿&#xff0c;能否进行一定优化。 2.操作实现&#xff1a; 1.思路&#xff1a;采取捕获最后deltaseconds来逐帧进行旋转或移动&#xff0c;使动作显得不那么卡顿。 .2.首先在引擎中建立映射&a…
最新文章