我这里不写关于 es的部署,如果要看es的部署,请移步 ~
<!-- ES搜索 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- elasticsearch -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.5.4</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.5.4</version>
</dependency>
这里呢
不建议引用最新的包,
至于原因嘛,有很多,例如,我的jdk还是1.8。
我用的是yml,只说yml。
spring:
#指明es服务器地址
elasticsearch:
rest:
uris: http://103.59.148.103:9200
username: hehe
password: *********
下面,进入重点课程,es的java使用。
/**
* @Author: zhaoz
* @CreateTime: 2022年11月11日
* @Description: ES 数据结构
*/
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "test_console")
@Accessors(chain = true)
@Data
public class InfoEntity implements Serializable {
private static final long serialVersionUID = -2942121322430364691L;
@Id
@ApiModelProperty("id")
private String id;
@ApiModelProperty("info时间")
@Field(name = "info_time", type = FieldType.Date, format = {}, pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime infoTime;
@ApiModelProperty("标题")
@Field(name = "title", type = FieldType.Text, analyzer = "ik_max_word")
private String title;
@ApiModelProperty("内容")
@Field(name = "content", type = FieldType.Text, analyzer = "ik_max_word")
private String content;
@ApiModelProperty("地址")
@Field(name = "address", type = FieldType.Text, analyzer = "ik_max_word")
private String address;
}
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@PostMapping("/createdIndex2")
@ApiOperation(value = "学习创建索引")
public String createdIndex2(@RequestParam("index") String index) {
// 判断索引是否存在
try {
GetIndexRequest getIndexRequest = new GetIndexRequest(index).local(false).humanReadable(true);
if (client.indices().exists(getIndexRequest, RequestOptions.DEFAULT)) {
return "存在索引!";
} else {
// 设置settings映射
Settings settings = Settings.builder().put("number_of_shards", 1).put("number_of_replicas", 0).build();
// 设置mapping映射
XContentBuilder mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject("properties")
// keyId
.startObject("id").field("type", "long").endObject()
// title
.startObject("info_title").field("type", "keyword").endObject()
// content
.startObject("info_content").field("type", "text").endObject()
// birthday
.startObject("info_time")
.field("type", "date")
.field("format", "yyyy-MM-dd HH:mm:ss")
.field("ignore_malformed", true).endObject()
// address
.startObject("address").field("type", "text").endObject()
.endObject().endObject();
boolean createIndexResponse = getCreateIndexResponse(new CreateIndexRequest(index).settings(settings).mapping(mapping));
if (createIndexResponse) {
return "创建索引成功";
} else {
return "创建索引失败";
}
}
} catch (Exception e) {
e.printStackTrace();
return e.getLocalizedMessage();
}
}
private boolean getCreateIndexResponse(CreateIndexRequest createIndexRequest) throws Exception {
String index = createIndexRequest.index();
try {
// 超时时间设置为 1m
createIndexRequest.setTimeout(TimeValue.timeValueMinutes(1));
CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
if (createIndexResponse.isAcknowledged()) {
// 创建ES索引成功
return true;
} else {
// 创建ES索引失败
return false;
}
} catch (Exception e) {
throw new Exception("创建ES索引[" + index + "]异常", e);
}
}
删除索引 会删除数据
/**
* 删除索引 会删除数据
* @param index
* @return
*/
@DeleteMapping("/deleteIndex")
@ApiOperation(value = "学习删除索引")
public String deleteIndex(@RequestParam("index") String index) {
// 判断索引是否存在
try {
GetIndexRequest getIndexRequest = new GetIndexRequest(index).local(false).humanReadable(true);
if (client.indices().exists(getIndexRequest, RequestOptions.DEFAULT)) {
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(index);
deleteIndexRequest.indicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN);
AcknowledgedResponse acknowledgedResponse = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
if (acknowledgedResponse.isAcknowledged()) {
return "删除索引成功";
} else {
return "删除索引失败";
}
} else {
return "索引不存在!";
}
} catch (Exception e) {
e.printStackTrace();
return e.getLocalizedMessage();
}
}
@PostMapping("/addESFieldContent")
@ApiOperation(value = "添加字段内容(map格式)")
public R addESFieldContent(@RequestBody Map<String, String> maps) throws IOException {
// 可以使用Map作为参数
IndexRequest indexRequest = new IndexRequest();
indexRequest.index(INDEXES_TYPE);
indexRequest.source(maps);
// 可以使用XConttentBuilder构建内容
// XContentBuilder builder = XContentFactory.jsonBuilder();
// builder.startObject();
// {
// builder.field("user", "kimchy");
// builder.timeField("postDate", new Date());
// builder.field("message", "trying out Elasticsearch");
// }
// builder.endObject();
// IndexRequest indexRequest = new IndexRequest("posts")
// .id("1").source(builder);
// 发送请求到ES
IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
return R.ok(response);
}
还有一种,就需要用到我们创建好的实体类InfoEntity
package com.whisper.db.esRepository;
import com.whisper.db.domain.InfoEntity;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface InfoRepository extends ElasticsearchRepository<InfoEntity, String> {
}
@Autowired
private InfoRepository infoRepository;
@PostMapping("/addESContent")
@ApiOperation(value = "保存es内容")
public R addESContent(@RequestBody InfoEntity entity) throws Exception {
InfoEntity save = infoRepository.save(entity);
return R.ok(save);
}
@GetMapping("/match/all")
@ApiOperation(value = "学习数据查询")
public String matchAll(@RequestParam("index") String index) throws IOException {
// String index = "test_console";
SearchRequest request = new SearchRequest(index);
//2.指明使用matchall查询
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchAllQuery());
// 查询条数
builder.size(10);
request.source(builder);
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.输出
return response.toString();
}
这里我只写一种我们可能会经常用到的修改方式;
@PutMapping("/editESFieldContent")
@ApiOperation(value = "修改字段内容")
public R editFieldContent(@RequestBody Map<String, String> maps) throws IOException {
// 这是我前面创建的索引,记得替换成自己的
String index = "test_console";
UpdateRequest update = new UpdateRequest();
update.index(index).id(maps.get("id"));
// 拓展:局部更新可以这样写:update.doc(XContentType.JSON, "name", "李四", "age", 25);,其中"name"和"age"是User对象中的字段名称,而"小美"和25是对应的字段值
update.doc(XContentType.JSON, "info_title", maps.get("title"), "info_content", maps.get("content"));
// 全部更新需要重新传入数据
// update.doc(JSONObject.toJSONString(maps), XContentType.JSON);
// 3、发送请求到ES
UpdateResponse response = client.update(update, RequestOptions.DEFAULT);
return R.ok(response);
}
这里需要注意 map里面的id是es生成的id

再附上一个有用的es 语句。
POST /test_console/_doc/LWNgf4QBMMqlRJmSXSlf/_update
{
"doc":{
"info_title": "外交部发言人回应达苏恐袭案宣判:这是对正义的伸张、对遇难中国同胞的告慰。"
}
}
@GetMapping("/match/search")
@ApiOperation(value = "es模糊搜索")
public String matchSearch(
@RequestParam("index") String index,
@RequestParam("keyword") String keyword) throws IOException {
if (StringUtils.isEmpty(keyword)) {
return "";
}
// String index = "test_console";
SearchRequest request = new SearchRequest(index);
//2.指明使用match查询
SearchSourceBuilder builder = new SearchSourceBuilder();
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("info_content", keyword);
builder.query(matchQueryBuilder);
builder.size(10);
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return response.toString();
}
@GetMapping("/multiMatch/search")
@ApiOperation(value = "es模糊搜索")
public String multiMatch(
@RequestParam("index") String index,
@RequestParam("keyword") String keyword) throws IOException {
if (StringUtils.isEmpty(keyword)) {
return "";
}
// String index = "test_console";
SearchRequest request = new SearchRequest(index);
//2.指明使用match查询
String[] fieldNames = {"info_content", "info_title"};
SearchSourceBuilder builder = new SearchSourceBuilder();
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keyword, fieldNames);
builder.query(multiMatchQueryBuilder);
builder.size(10);
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return response.toString();
}
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keyword, fieldNames).type("phrase");
这里使用的也比较简单 就是.type(“phrase”)
4. 查询不同字段不同关键字的查询
这里使用的是 es 查询语句的 bool query
需要注意的是 must、和 should的区别。
// 附上 es的语法,更清晰的明白Java的写法。
GET /test_console/_search
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "宙斯盾号军舰89",
"fields": ["info_content","info_title"],
"type": "phrase"
}
},
{
"multi_match": {
"query": "空军",
"fields": ["info_content","info_title"],
"type": "phrase"
}
}
]
}
},
"from": 0,
"size": "20"
}
@GetMapping("/match/bool/multiQuery")
@ApiOperation(value = "es模糊搜索")
public R matchBoolPhraseQuery(@Param("index") String index,
@Param("fields") String fields,
@Param("keywords") String keywords) throws IOException {
// String index = "test_console";
SearchRequest request = new SearchRequest(index);
SearchSourceBuilder builder = new SearchSourceBuilder();
if (StringUtils.isEmpty(keywords)) {
builder.query(QueryBuilders.matchAllQuery());
builder.size(10);
} else {
String[] keywordg = keywords.split(" ");
//2.指明使用match查询
String[] fieldNames = {};
if (StringUtils.isNotEmpty(fields)) {
fieldNames = fields.split(" ");
} else {
fieldNames = new String[]{"news_content", "news_title"};
}
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
for (String keyword:keywordg) {
boolQueryBuilder.must(QueryBuilders.multiMatchQuery(keyword, fieldNames).type("phrase"));
}
builder.query(boolQueryBuilder);
builder.size(10);
}
request.source(builder);
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 结果解析
SearchHits hits = response.getHits();
List<Map<String, Object>> results = new ArrayList<>();
for (SearchHit documentFields : hits.getHits()) {
Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
results.add(sourceAsMap);
}
return R.ok(results);
}
继续学习中。。。
敬请期待 ~
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po