Solr 部署与使用踩坑全记录 (3)

2、Slave 查看它本地是否有这些文件,然后它会开始下载缺失的文件(使用命令 filecontent)。如果与 Master 连接失败,就会重新连接,如果重试 5 次还是没有成功,就会 Slave 停止同步。

3、文件被同步到了一个临时目录(index.时间戳 格式的文件夹名称,例如:index.20190614133600008)。旧的索引文件还存放在原来的文件夹中,同步过程中出错不会影响到 Slave,如果同步过程中有请求访问,Slave 会使用旧的索引。

4、当同步结束后,Slave 就会删除旧的索引文件使用最新的索引。

我们项目中 6.7G 的索引文件(279 万条记录),大概只用了 12 分钟左右就同步完成了,平均每秒的同步速度大约在 10M 左右。

Solr 部署与使用踩坑全记录

Solr 部署与使用踩坑全记录

注意事项: 如果主从的数据源配置的不一致,很可能导致从服务器无法同步索引数据。

在项目中使用 Solr 在 Java 项目中使用 Solr

SolrJ 是 Solr 的官方客户端,文档地址:https://lucene.apache.org/solr/7_7_2/solr-solrj/。
使用 maven 添加:

<!-- https://mvnrepository.com/artifact/org.apache.solr/solr-solrj --> <dependency> <groupId>org.apache.solr</groupId> <artifactId>solr-solrj</artifactId> <version>7.7.2</version> </dependency>

查询索引文档:

String keyword = "苹果"; Map<String, String> queryParamMap = new HashMap<String, String>(); queryParamMap.put("q", "*:*"); queryParamMap.put("fq", keyword); MapSolrParams queryParams = new MapSolrParams(queryParamMap); QueryResponse queryResponse = client.query("posts", queryParams); SolrDocumentList results = queryResponse.getResults();

添加和更新索引文档:

// 通过 属性 添加到索引中 SolrInputDocument doc = new SolrInputDocument(); doc.addField("id", "10000"); doc.addField("post_title", "test-title"); doc.addField("post_name", "test-name"); doc.addField("post_excerpt", "test-excerpt"); doc.addField("post_content", "test-content"); doc.addField("post_date", "2019-06-18 14:56:55"); client.add("posts", doc); // 通过 Bean 添加到索引中 Post post = new Post(); post.setId(10001); post.setPost_title("test-title-10001"); post.setPost_name("test-name"); post.setPost_excerpt("test-excerpt"); post.setPost_content("test-content"); post.setPost_date(new Date()); client.addBean("posts", post); client.commit("posts");

具体代码可以参考我 GitHub 中的示例,这里就不详细列出了。

在 DotNet 项目中使用 Solr

SolrNet:https://github.com/mausch/SolrNet

通过 Nuget 添加 SolrNet:

Install-Package SolrNet

首先定义一个索引对象 PostDoc:

/// <summary> /// 文章 doc。 /// </summary> [Serializable] public class PostDoc { [SolrUniqueKey("id")] public int Id { get; set; } [SolrField("post_title")] public string Title { get; set; } [SolrField("post_name")] public string Name { get; set; } [SolrField("post_excerpt")] public string Excerpt { get; set; } [SolrField("post_content")] public string Content { get; set; } [SolrField("post_date")] public DateTime PostDate { get; set; } }

在项目的 Startup 类中初始化 SolrNet:

SolrNet.Startup.Init<PostDoc>("http://localhost:8983/solr/posts");

添加或更新文档操作:

// 同步添加文档 solr.Add( new PostDoc() { Id = 30001, Name = "This SolrNet Name", Title = "This SolrNet Title", Excerpt = "This SolrNet Excerpt", Content = "This SolrNet Content 30001", PostDate = DateTime.Now } ); // 异步添加文档(更新) await solr.AddAsync( new PostDoc() { Id = 30001, Name = "This SolrNet Name", Title = "This SolrNet Title", Excerpt = "This SolrNet Excerpt", Content = "This SolrNet Content Updated 30001", PostDate = DateTime.Now } ); // 提交 ResponseHeader responseHeader = await solr.CommitAsync();

删除文档操作:

// 使用文档 Id 删除 await solr.DeleteAsync("300001"); // 直接删除文档 await solr.DeleteAsync(new PostDoc() { Id = 30002, Name = "This SolrNet Name", Title = "This SolrNet Title", Excerpt = "This SolrNet Excerpt", Content = "This SolrNet Content 30002", PostDate = DateTime.Now }); // 提交 ResponseHeader responseHeader = await solr.CommitAsync();

搜索并对结果进行排序,在不传入分页参数的情况下 SolrNet 会返回所有满足条件的结果。

// 排序 ICollection<SortOrder> sortOrders = new List<SortOrder>() { new SortOrder("id", Order.DESC) }; // 使用查询条件并排序 SolrQueryResults<PostDoc> docs = await solr.QueryAsync("post_title:索尼", sortOrders);

使用字段筛选的另一种方式:

// 使用条件查询 SolrQueryResults<PostDoc> posts = solr.Query(new SolrQueryByField("id", "30000"));

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgjpw.html