boot整合solr

news2024/10/6 0:34:55

换了新项目组,技术相对老些,于是用boot框架简单记录下!

安装

下载路径:https://solr.apache.org/downloads.html

Windows环境

下载solr-8.2.0.zip包并解压缩,以管理员身份打开cmd,执行 solr cmd 命令启动solr

访问地址:ip:8983/

Linux环境

下载solr-8.2.0.tgz包 并执行以下命令

#1.解压缩

cd /opt
tar -xvf solr-8.2.0.tgz

#2.编辑sh脚本

cd ​solr-8.2.0/bin

vim solr.in.sh

补充内容:

​SOLR_ULIMIT_CHECKS=false

#3.启动

./solr start -force

 访问地址:ip:8983/

常用概念

核心(索引/表)

核心core:和数据库中的表一个意思,只是术语不同。可以看到页面上有个Core Admin,这个就是管理core的。

文档 doc

文档doc:相当于数据库中的一行数据。一个core由多条doc组成。

 结构 schema

结构schema:相当于数据库的表结构。常见结构schema:字段、字段类型、唯一键

分词

分词:就是将搜索内容拆分成一个个的词组。这个和以往数据库模糊匹配还不一样。

例如 在百度搜索时,搜索“我是好人”,会将搜索内容分成 我,是,好人。然后判断这几个分词在索引库中的出现次数,根据权重返回匹配信息。若用传统数据库mysql或oracle这种,直接会去用“我是好人”去模糊查询数据库,最后查询出的结果只能是 %我是好人% 这种数据。

但是搜索引擎会匹配出 %我%是%好人% 的数据。

倒排索引(反向索引)

说到倒排索引,提下正向索引。例如搜索“我是好人”,于是将分词 我,是,好人 分别去遍历每个文档,看是否有匹配数据。

倒排索引是 以分词为主键,文档ID为值的结构存储方式,其中文档ID升序存储,逗号分隔记录,节省了很大存储空间。当有搜索内容,只需分词后去匹配已倒排索引的数据得出最终的文档ID。

field标签常用属性

字段名称 name

字段类型 type

支持字段类型:

string 字符串
int, long 整数
float, double 浮点数
date 日期时间
bool 布尔类型
text 文本类型
binary 二进制类型

是否创建索引 indexed

indexed:当前字段是否创建索引,默认是true。创建索引后,可支持对该字段的搜索和过滤。

是否存储 sorted

sorted:当前字段是否存储到solr本身的存储库中,默认是true。此时不需要再次查询数据源显示数据。

是否启用点列存储 docValues

docValues:是否启用点列存储,默认是false。若需要做排序或者聚合查询处理都需要设置为true

是否多值 multiValues

multiValues:是否存储多个值,默认是false。若类型是数组,则需要设置为true。

安装ik中文分词器

版本与solr保持一致

下载地址:https://central.sonatype.com/artifact/com.github.magese/ik-analyzer

1.将ik-analyzer-8.2.0.jar包传输到/opt/solr-8.2.0/server/solr-webapp/webapp/WEB-INF/lib目录下

2.managed-schema文件补充  分词字段定义

<fieldType name="text_ik" class="solr.TextField">
   <analyzer type="index">
      <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/>
      <filter class="solr.LowerCaseFilterFactory"/>
   </analyzer>
   <analyzer type="query">
      <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/>
      <filter class="solr.LowerCaseFilterFactory"/>
   </analyzer>
</fieldType>

将需要分词的字段类型调整为 text_ik

<field name="remarks" type="text_ik" indexed="true" stored="true" />

3.重启solr

./bin/solr stop -all
./bin/solr start -force

查看结果

修改分词器后,需要将索引删除后重新加载,solr重启后导入数据,方可根据分词器查询。

常用查询

通配符   

?匹配单个字符;

* 匹配任意个字符;

连接符   

&& 条件且;

|| 条件或;

查询   

value值用"",表示该值是精确查询;

例如remark:"备注" ;查询remark字段只为备注的文档

NOT查询 

value值用(* NOT "value1" NOT "value2"),表示不查询value值为value1和value2;

例如remark:(* NOT"送货") ;查询remark字段不为送货的文档

范围查询

value值用[v1 TO v2] 表示范围查询,[]表示包含,{}表示不包含;

例如id:[1 TO 2} 查询1<=id<2的文档

创建索引

在/opt/solr-8.2.0/server/solr目录下创建文件夹person

#1.创建文件夹

mkdir person

#2.将自带文件复制到该目录下

cp -R solr-8.2.0/server/solr/configsets/_default/conf/* solr-8.2.0/server/solr/person

修改managed-schema文件

<?xml version="1.0" encoding="UTF-8" ?>

<schema name="default-config" version="1.6">

    <!--  默认字段,不需要的可以删除  -->
    <field name="id" type="long" indexed="true" stored="true" required="true" multiValued="false" />
	<field name="_version_" type="long" indexed="true" stored="true"/>
    <field name="_text_" type="text_general" indexed="true" stored="false" multiValued="true"/>
    
    <!--  定义字段 根据情况补充 -->
    <field name="p_no" type="string" indexed="true" stored="true" required="true" multiValued="false" />
    <field name="p_name" type="string" indexed="true" stored="true" required="true" multiValued="false" />
    <field name="create_time" type="date" indexed="true" stored="true" required="true" multiValued="false" />
    <field name="create_user" type="string" indexed="true" stored="true" required="true" multiValued="false" />
    <field name="remarks" type="text_ik" indexed="true" stored="true" required="true" multiValued="false" />
    <field name="loves" type="string" indexed="true" stored="false" required="true" multiValued="true" />

    <uniqueKey>id</uniqueKey>

    <!-- 要声明使用的type -->
    <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="string" class="solr.StrField" sortMissingLast="true" docValues="true" />
    <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="date" class="solr.TrieDateField" precisionStep="0" positionIncrementGap="0"/>
    
	<!-- 保留 -->
    <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100" multiValued="true">
      <analyzer type="index">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
      <analyzer type="query">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
        <filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
    </fieldType>
	
	<!-- 中文分词器 -->
	<fieldType name="text_ik" class="solr.TextField">
		<analyzer type="index">
		  <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/>
		  <filter class="solr.LowerCaseFilterFactory"/>
		</analyzer>
		<analyzer type="query">
		  <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/>
		  <filter class="solr.LowerCaseFilterFactory"/>
		</analyzer>
	</fieldType>
</schema>

修改solrconfig.xml文件

将所有调用及配置的add-schema-fields删除

solr设置账号密码

详情可见 前辈文章,下面也有记录

/opt/solr-8.2.0/server/etc目录

新建verify.properties文件,内容为 

# 用户名 密码 权限
solr: solr,admin

/opt/solr-8.2.0/server/contexts 目录

补充solr-jetty-context.xml文件,内容为

<!--添加配置权限认证:在文件configure中添加获取用户文件的配置,内容如下:-->
  <Get name="securityHandler">    
         <Set name="loginService">    
                 <New class="org.eclipse.jetty.security.HashLoginService">    
                        <Set name="name">verify—name</Set> 
                        <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/verify.properties</Set>    
                 </New>    
         </Set>    
  </Get>

/opt/solr-8.2.0/server/solr-webapp/webapp/WEB-INF目录

补充web.xml文件,内容为

<!--重新配置 security-resource-collection (删除之前的security-constraint,会导致登录的配置无效)-->
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Solr</web-resource-name>
      <url-pattern>/</url-pattern>
    </web-resource-collection>   
     <auth-constraint>      
        <role-name>admin</role-name> 
     </auth-constraint> 
  </security-constraint>

    <login-config>      
            <auth-method>BASIC</auth-method> 
            <realm-name>verify-name</realm-name>   
    </login-config>

 重启solr,账号密码为solr/solr

boot整合

pom.xml文件补充依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>

application.yml文件补充配置

spring:
  data:
    solr:
      host: http://192.168.28.196:8983/solr # solr 服务地址
      username: solr #用户名
      password: solr #密码
      connectionTimeout: 10000 #连接超时
      socketTimeout: 3000 #读取超时

启动类开启solr配置

@EnableSolrRepositories(basePackages="com.example.demo.repository")

solr配置

package com.example.demo.config;

import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthState;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpCoreContext;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.URI;

/**
 * @Auther: lr
 * @Date: 2024/6/6 16:57
 * @Description:
 */
@Configuration
public class SolrConfig {

    @Value("${spring.data.solr.username}")
    private String username;

    @Value("${spring.data.solr.password}")
    private String password;

    @Value("${spring.data.solr.host}")
    private String url;

    @Value("${spring.data.solr.connectionTimeout}")
    private Integer connectionTimeout;

    @Value("${spring.data.solr.socketTimeout}")
    private Integer socketTimeout;

    @Bean
    public HttpSolrClient solrClient(){

        //solr无账号密码
//        return new HttpSolrClient.Builder(url)
//                .withConnectionTimeout(connectionTimeout)
//                .withSocketTimeout(socketTimeout)
//                .build();

        //solr有账号密码 认证信息拦截
        CredentialsProvider provider = new BasicCredentialsProvider();
        final URI uri = URI.create(this.url);
        provider.setCredentials(new AuthScope(uri.getHost(), uri.getPort()),
                new UsernamePasswordCredentials(this.username, this.password));
        HttpClientBuilder builder = HttpClientBuilder.create();
        // 指定拦截器,用于设置认证信息
        builder.addInterceptorFirst(new SolrAuthInterceptor());
        builder.setDefaultCredentialsProvider(provider);
        CloseableHttpClient httpClient = builder.build();
        return new HttpSolrClient.Builder(this.url)
                .withHttpClient(httpClient)
                .withConnectionTimeout(connectionTimeout)
                .withSocketTimeout(socketTimeout)
                .build();
    }

    public static class SolrAuthInterceptor implements HttpRequestInterceptor {
        @Override
        public void process(final HttpRequest request, final HttpContext context) {
            AuthState authState = (AuthState) context.getAttribute(HttpClientContext.TARGET_AUTH_STATE);
            if (authState.getAuthScheme() == null) {
                CredentialsProvider provider =
                        (CredentialsProvider) context.getAttribute(HttpClientContext.CREDS_PROVIDER);
                HttpHost httpHost = (HttpHost) context.getAttribute(HttpCoreContext.HTTP_TARGET_HOST);
                AuthScope scope = new AuthScope(httpHost.getHostName(), httpHost.getPort());
                Credentials credentials = provider.getCredentials(scope);
                authState.update(new BasicScheme(), credentials);
            }
        }
    }

}

实体类

package com.example.demo.entity;

import lombok.Data;
import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.annotation.Id;
import org.springframework.data.solr.core.mapping.Indexed;
import org.springframework.data.solr.core.mapping.SolrDocument;

import java.util.Date;
import java.util.List;

/**
 * @Auther: lr
 * @Date: 2024/6/7 14:52
 * @Description:
 */
@Data
@SolrDocument(collection = "person")
public class Person {

    @Id
    @Indexed(name = "id", type = "long")
    @Field("id")
    private Long id;

    @Indexed(name = "p_no", type = "string")
    @Field("p_no") //@Field 用于solr结果转实体类对象
    private String pNo;

    @Indexed(name = "p_name", type = "string")
    @Field("p_name")
    private String pName;

    @Indexed(name = "create_time", type = "date")
    @Field("create_time")
    private Date createTime;

    @Indexed(name = "create_user", type = "string")
    @Field("create_user")
    private String createUser;

    @Indexed(name = "remarks", type = "text_ik")
    @Field("remarks")
    private String remarks;

    @Indexed(name = "loves", type = "string")
    @Field("loves")
    private List<String> loves;
}

dao层

package com.example.demo.repository;

import com.example.demo.entity.Person;
import org.springframework.data.solr.repository.SolrCrudRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @Auther: lr
 * @Date: 2024/6/7 11:28
 * @Description:
 */
@Repository
public interface PersonRepository extends SolrCrudRepository<Person, Long> {

    List<Person> findAll();

    List<Person> findByRemarks(String remarks);
}

controller类

package com.example.demo.controller;

import com.example.demo.entity.Person;
import com.example.demo.repository.PersonRepository;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.List;

/**
 * @Auther: lr
 * @Date: 2024/6/7 9:42
 * @Description:
 */
@RestController
@RequestMapping("/person")
public class SolrController {

    @Autowired
    PersonRepository repository;

    @PostMapping("/addData")
    public void addData(@RequestBody Person person) throws Exception{
        repository.save(person);
    }

    @GetMapping("/queryAll")
    public List<Person> search() throws SolrServerException, IOException {

        List<Person> list  = repository.findAll();
        return list;
    }

    @GetMapping("/queryByRemarks")
    public List<Person> search(@RequestParam("remarks") String remarks) throws SolrServerException, IOException {

        List<Person> list  = repository.findByRemarks(remarks);
        return list;
    }

    @Autowired
    HttpSolrClient solrClient;

    @GetMapping("queryByLoves")
    public List<Person> queryByLoves(@RequestParam("love") String love) throws IOException, SolrServerException {

        //设置查询条件
        SolrQuery query = new SolrQuery();
        if (!StringUtils.isEmpty(love)) {
            query.setQuery("loves:" + love);
        }
        if(StringUtils.isEmpty(query.getQuery())){
            query.setQuery("*:*");
        }
        query.setStart(0);
        query.setRows(5);
        QueryResponse response = solrClient.query("person",query);
        List<Person> list = response.getBeans(Person.class);
        return list;
    }
}

接口调用测试

在索引写文档信息

在索引查询文档信息

其他查询(聚合分组查询group)根据项目而定!!!

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

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

相关文章

WordPress 高级缓存插件 W3 Total Cache Pro 详细配置教程

说起来有关 WordPress 缓存插件明月已经发表过不少文章了,但有关 W3 Total Cache Pro 这个 WordPress 高级缓存插件除了早期【网站缓存插件 W3 Total Cache,适合自己的才是最好的!】一文后就很少再提及了,最近因为明月另一个网站【玉满斋】因为某些性能上的需要准备更换缓存…

微服务中调用common模块中的工具类

首先查看common类中的pom文件中的信息 然后再在所需要使用的微服务模块中进行注入 就可以使用其中的工具类了

pyqt opengl 小黑块

目录 OpenGLWidget_g初始化函数&#xff1a; 解决方法&#xff1a;把初始化函数的parent去掉 pyqt opengl 小黑块 原因&#xff1a; 创建OpenGLWidget_g的时候把main_window作为父类&#xff08;self&#xff09;传进去了&#xff0c; self.opengl_widget OpenGLWidget_g(…

前端nvm的安装和使用nodejs多版本管理2024

nvm的安装和使用 1、简介 nvm是一个管理nodejs版本的工具。在实际的开发中&#xff0c;项目的开发依赖需要的nodejs版本运行环境不同&#xff0c;此时我们就需要使用nvm来进行不同nodejs版本的切换。其实就是一个方便的node版本管理工具。 注意&#xff1a;如果有安装过node&a…

PySpark教程(001):基础准备与数据输入

PySpark 学习目标 了解什么是Spark、PySpark了解为什么学习PySpark了解如何和大数据开发方向进行衔接 Spark是什么&#xff1f; Apache Spark是用于大规模数据处理的统一分析引擎。 简单来说&#xff0c;Spark是一款分布式的计算框架&#xff0c;用于调度成百上千的服务器…

算法设计与分析(5题Python版)

1、阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有N堆金币&#xff0c;第i堆金币的总重量和总价值分别是m,v。阿里巴巴有一个承重量为T的背包&#xff0c;但并不一定有办法将全部的金币都装进去。 他想装走尽可能多价值的金币&#xff0c;所有金币都可以随意分割&#xff0c;分…

攻防世界---misc---Excaliflag

1、题目描述&#xff0c;下载附件是一张图片 2、用winhex分析&#xff0c;没有发现奇怪的地方 3、在kali中使用binwalk -e 命令&#xff0c;虽然分离出来了一些东西&#xff0c;但是不是有用的 4、最后用stegsolve分析&#xff0c;切换图片&#xff0c;发现有字符串&#xff0c…

tcp协议中机制的总结

目录 总结 分析 三次握手 总结 分析 其中,序列号不止用来排序,还可以用在重传时去重 确认应答是机制中的核心 因为都需要依靠应答来拿到协议字段,从而判断是否触发机制 保证可靠性的策略也可以提高效率,比如: 流量控制,可以根据多个因素来动态调整数据发送量拥塞控制也是,让…

XSS(跨站脚本攻击)

1.什么是xss XSS全称&#xff08;Cross Site Scripting&#xff09;跨站脚本攻击&#xff0c;为了避免和CSS层叠样式表名称冲突&#xff0c;所以改为了 XSS&#xff0c;是最常见的Web应用程序安全漏洞之一,XSS是指攻击者在网页中嵌入客户端脚本&#xff0c;通常是JavaScript编写…

两句话让LLM逻辑推理瞬间崩溃!!

一道简单的逻辑问题&#xff0c;竟让几乎所有的LLM全军覆没&#xff1f; 对于人类来说&#xff0c;这个名为「爱丽丝梦游仙境」&#xff08;AIW&#xff09;的测试并不算很难—— 「爱丽丝有N个兄弟&#xff0c;她还有M个姐妹。爱丽丝的兄弟有多少个姐妹&#xff1f;」 稍加思考…

Git发布正式

一般我们开发都是在测试环境开发&#xff0c;开发完成后再发布到正式环境。 一.分支代码合并到主分支1.首先切换到自己的分支(比如分支叫&#xff1a;dev)git checkout dev2.把本地分支拉取下来git pull 或者 git pull origin dev3.切换到主分支mastergit checkout master4.更新…

Unity | Shader基础知识(番外:了解内置Shader-Standard<二>)

目录 前言 一、Standard参数详解 1.NormalMap法线贴图 2.HeightMap高度贴图 3.Occlusion遮挡贴图 4.DetailMask细节遮挡 5.Emission自发光 6.Tiling铺地砖和Offset偏移度 二、作者的碎碎念 前言 Unity | Shader基础知识(番外&#xff1a;了解内置Shader-Standard&#x…

在WSL2下配置Pytorch(Linux+Anaconda+PyTorch-GPU)

之前使用过双系统、虚拟机的ubunutu 效果都不是很好&#xff0c;要么切换系统太麻烦&#xff0c;要么太卡顿 最近在尝试WSL子系统&#xff0c;没有想到还是有很多坑 记录一下配置的过程 一、NVIDIA显卡的安装 因为WSL和Windows的显卡驱动不能互通&#xff0c;所以在子系统上需…

Redis的缓存击穿、缓存穿透和缓存雪崩是什么?怎么预防?

Redis的缓存击穿、缓存穿透和缓存雪崩是什么&#xff1f;怎么预防&#xff1f; 前言缓存击穿定义解决思路实现加锁设置过期时间Lua脚本刷新锁 缓存穿透定义实现 缓存雪崩定义解决思路 总结 前言 最近在CSDN上看到了一篇博客&#xff0c;Redis缓存击穿、雪崩、穿透&#xff01;…

双列集合 HashMap以及TreeMap底层原理

双列集合 特点&#xff1a; 双列集合一次需要存一对数据&#xff0c;分别为键和值 键不能重复&#xff0c;值可以重复 键和值是一一对应的&#xff0c;每个键只能找到自己对应的值 键和值这个整体在Java中叫做“Entry对象” Map的常见API Map是双列集合的顶层接口&#xff0c;…

第十一篇——信息增量:信息压缩中的保守主义原则

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 通过信息中的保守主义&#xff0c;我想到了现实中人的保守主义一样&#…

JavaScript前端技术入门教程

引言 在前端开发的广阔天地中&#xff0c;JavaScript无疑是最耀眼的一颗明星。它赋予了网页动态交互的能力&#xff0c;让网页从静态的文本和图片展示&#xff0c;进化为可以与用户进行实时交互的丰富应用。本文将带您走进JavaScript的世界&#xff0c;为您提供一个入门级的教…

文件操作(Python和C++版)

一、C版 程序运行时产生的数据都属于临时数据&#xff0c;程序—旦运行结束都会被释放通过文件可以将数据持久化 C中对文件操作需要包含头文件< fstream > 文件类型分为两种: 1. 文本文件 - 文件以文本的ASCII码形式存储在计算机中 2. 二进制文件- 文件以文本的二进…

【InternLM实战营第二期笔记】06:Lagent AgentLego 智能体应用搭建

文章目录 讲解为什么要有智能体什么是 Agent智能体的组成智能体框架AutoGPTReWooReAct Lagent & Agent LegoAgentLego 实操Lagent Web Demo自定义工具 AgentLego&#xff1a;组装智能体“乐高”直接使用作为智能体&#xff0c;WebUI文生图测试 Agent 工具能力微调 讲解 为…

DDMA信号处理以及数据处理的流程---原始数据生成

Hello&#xff0c;大家好&#xff0c;我是Xiaojie&#xff0c;好久不见&#xff0c;欢迎大家能够和Xiaojie一起学习毫米波雷达知识&#xff0c;Xiaojie准备连载一个系列的文章—DDMA信号处理以及数据处理的流程&#xff0c;本系列文章将从目标生成、信号仿真、测距、测速、cfar…