I have been working on many application during my career.  Many if not all had some searching capabilities.  The more complex the search got, the harder it was to control its performance and impact on database transactions.  If you also would like to support full text search, your problems become larger.  We could use Full text search capabilities in Oracle or SQL Server, but we would need to setup a separate instance if we want to limit impact on the transactions yet again.  Or we can pick another solution, better suited to solve the problem at hand.  This is where Elastic Search comes in.

It is a web services layer setup on top of Lucene, a search engine written in Java.  As a result, we will need to have Java Runtime installed on all machine where we are going to install Elastic Search, including developer machines.  You can download it from oracle web site, and it is free.  http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html.  I would recommend making sure you have 64 bit installed.

You can download Elastic Search at https://www.elastic.co/downloads/elasticsearch.  Let’s start by doing so. Once you have the zip file, we will install windows service that hosts Elastic Search on windows.  This is the easiest way to run Elastic on Windows.  Once you unzip the download, switch to bin folder using command window.  Then run service.bat to install windows service.  Just type the following

service install

If you get the following message: JAVA_HOME environment variable must be set.  We need to setup this environment variable.  Go to properties of “My Computer”.  Then select advanced system settings, then environment variables.  Add new system variable called JAVA_HOME.  It’s value should be something similar to “C:Program FilesJavajre1.8.0_74”.  Then run service install again.  You should see something like the following.  if so, you are done with step 1.

Next step is to start new .NET project.  I would pick class library to house our search code in.  We will test it using tests project.

So, start new class library project.  I’ll call mine Search.Library.  When we integrate Elastic with .NET, we should use .NET client library.  I use NEST, which is the best one in my opinion.  To install it use Nuget.  I would switch to NuGet package manager console window and type

install-package NEST

or you can use package manager window.  NEST will install ElasticSearch.Net package, one of its dependencies and JSON.NET.  We could then technically speaking start testing, but we need to take a few more steps in advance.

I have been using Elastic Search for a while.  In theory, you can use schema-less approach with it.  However, in practice, this does not work really well.  Schema has many advantages.  We can be very precise, especially for nullable data, when Elastic does not really know how to index the data.  So, if would apply default full text search approaches to all the data.  This may or may not be what we want.

In an example let’s define a class that we will use for samples.  Let’s call it Location, corresponding to a city.

namespace Search.Library { public class Location { public int CityId { get; set; } public string City { get; set; } public string Zip { get; set; } public string Type { get; set; } public string State { get; set; } public string County { get; set; } public string AreaCodes { get; set; } public double Latitude { get; set; } public double Longitude { get; set; } public string WorldRegion { get; set; } public string Country { get; set; } public int EstimatedPopulation { get; set; } public Coordinates Coordinates { get; set; } } }

Because we need to support geographic location, we defined a separate location type.

namespace Search.Library { public class Coordinates { public double Lat { get; set; } public double Lon { get; set; } } }

We need to configure the mappings in Elastic.  We may want to use free handed search on all fields, which in Elastic Search will be referred to as analyzed field.   Analyzed fields are broken into words then indexed for speedy word based search.  Say in the case of area codes we want to search similarly to LIKE ‘%%’ in SQL Server though.  Any such fields we need to flag as “not analyzed”.  In addition we may want to use custom analyzer to account for case sensitive search on not-analyzed fields.  We also want to use the same approach for all the fields that we want to use exact match on.  We should also think about primary keys.  In this case we want to flag CityId as id field in elastic search.  I feel that thinking about your mappings and queries upfront will save you some headaches down the road.

private void CreateMappings() { _client.Map<Location>(descriptor => { descriptor.Index(DefaultIndexName); descriptor.Properties(propertiesDescriptor => { propertiesDescriptor.Number(loc => loc.Name(location => location.CityId)); propertiesDescriptor.String(loc => loc.Name(location => location.City)); propertiesDescriptor.String(loc => loc.Name(location => location.Country)); propertiesDescriptor.String(loc => loc.Name(location => location.State)); propertiesDescriptor.String(loc => loc.Name(location => location.Type)); propertiesDescriptor.String(loc => loc.Name(location => location.Zip) .NotAnalyzed().Analyzer(LowerCaseAnalyzerName)); propertiesDescriptor.Number(loc => loc.Name(location => location.Latitude)); propertiesDescriptor.Number(loc => loc.Name(location => location.Latitude)); propertiesDescriptor.Number(loc => loc.Name(location => location.EstimatedPopulation)); propertiesDescriptor.GeoPoint(loc => { loc.Name(location => location.Coordinates); loc.LatLon(); return loc; }); return propertiesDescriptor; }); return descriptor; }); }

In the mapping creation above _client is an instance of ElasticClient.  Then we run through the property of our type, Location, and setup up each property.  In case of zip we set it up fot wild card search.  The reset of string properties are setup for stadard word base indexed search.  Finally, I setup location as type GeoPoint for spatial search.  We are going to run through the code in unit tests to make sure our mappings work Ok.

using Microsoft.VisualStudio.TestTools.UnitTesting; using Nest; namespace Search.Library.Tests { [TestClass] public class SearchTests { private ElasticClient _client; [TestInitialize] public void OnInit() { _client = new ElasticConfiguration().CreatElasticClient(); // just for testing. Should use custom index name. var indexExists = _client.IndexExists(new IndexExistsRequest(Indices.Parse(ElasticConfiguration.DefaultIndexName))); if (indexExists.Exists) { _client.DeleteIndex(new DeleteIndexDescriptor(Indices.Parse(ElasticConfiguration.DefaultIndexName))); } _client.Refresh(new RefreshRequest(Indices.All)); new ElasticConfiguration().SetupMappings(); } [TestMethod] public void Should_Create_Mappings() { var config = new ElasticConfiguration(); config.SetupMappings(); } [TestMethod] public void Should_Add_Data() { _client = new ElasticConfiguration().CreatElasticClient(); var loc = new Location { Type = "STANDARD", Coordinates = new Coordinates { Lat = 30, Lon = 40 }, Latitude = 30, CityId = 1, EstimatedPopulation = 23, State = "GA", City = "Atlanta", Zip = "30000", Country = "USA", AreaCodes = "33333 44444", County = "Gwinnett", Longitude = 40, WorldRegion = "North America" }; _client.Index(loc, descriptor => { descriptor.Index("default"); return descriptor; }); } } }

If we want to look at our mappings, we can easily do this in Chrome.  Go to extensions and search for “Sense”.  This will install Elastic Search plugin.  You can click on the plugin after that, and you will something similar to the following.

To look at the mappings, just type get _mapping and hit green arrow.

Our mappings look as follows.

{ "default": { "mappings": { "locations": { "properties": { "areaCodes": { "type": "string" }, "city": { "type": "string" }, "cityId": { "type": "double" }, "coordinates": { "type": "geo_point", "lat_lon": true }, "country": { "type": "string" }, "county": { "type": "string" }, "estimatedPopulation": { "type": "double" }, "latitude": { "type": "double" }, "longitude": { "type": "double" }, "state": { "type": "string" }, "type": { "type": "string" }, "worldRegion": { "type": "string" }, "zip": { "type": "string", "index": "not_analyzed", "analyzer": "customLowerCase" } } } } } }

We will discuss queries in subsequent posts.  You can download current project here.

Getting Started with Elastic Search in .NET的更多相关文章

  1. elastic search查询命令集合

    Technorati 标签: elastic search,query,commands 基本查询:最简单的查询方式 query:{"term":{"title" ...

  2. elastic search 学习笔记

    Elastic search在数据分析的应用中相当于一个数据库的搜索引擎. 跟MySQL类似,它有自己的查询语言,只不过不是关系型数据库,属于NoSQL. 可以根据索引从分布式服务器文件系统中快速存取 ...

  3. elastic search 学习 一

    初步阅读了elastic search 的文档,并使用command实践操作. 大概明白其概念模型.

  4. 分库分表后跨分片查询与Elastic Search

    携程酒店订单Elastic Search实战:http://www.lvesu.com/blog/main/cms-610.html 为什么分库分表后不建议跨分片查询:https://www.jian ...

  5. 自学elastic search

    工作也有一段时间了,虽然来这个公司之后学会了几门不同的语言,但想拨尖还是任重道远. 想往高级程序员甚至是架构师方向发展.他仍然是我的学习对象.我现在做着的,无非是他玩剩下的罢了. luncene之前有 ...

  6. Elastic Search 上市了,市值翻倍,这群人财务自由了!

    国庆长假,大部分人还深浸在风花雪月之中,而就在昨天(美国时间10月5号),我们 Java 程序员所熟知的大名鼎鼎的 Elastic Search 居然在美国纽约证券交易所上市了! 当说到搜索时,大部分 ...

  7. Elastic Search 安装和配置

    目标 部署一个单节点的ElasticSearch集群 依赖 java环境 $java -version java version "1.8.0_161" Java(TM) SE R ...

  8. [elastic search][redis] 初试 ElasticSearch / redis

    现有项目组,工作需要. http://www.cnblogs.com/xing901022/p/4704319.html Elastic Search权威指南(中文版) https://es.xiao ...

  9. elastic search文档详解

    在elastic search中文档(document)类似于关系型数据库里的记录(record),类型(type)类似于表(table),索引(index)类似于库(database). 文档一定有 ...

  10. elastic search 查询

    eelastic search主要有两种查询方式,一种是查询字符串,一种是请求体(json格式)查询. 查询字符串: 查询字符串的功能相对简单,使用容易. 比如GET http://localhost ...

随机推荐

  1. socket & pipe note

    [socket & pipe note] 1.socket类型 2.大小端 3.socketpair 如何创建全双工管道? 直接的办法当然是pipe两次,创建两组管道,但是有没有更简单的呢? ...

  2. Matlab界面清洗

    保持干净清爽的编程界面可以给人以简洁明朗的享受,Matlab可以对涉及到的4个界面进行清洗: ①  Clear Figure ; ② Clear Command window; ③ Clear Wor ...

  3. soapUI参数中文乱码问题解决方法&soap UI工具进行web接口测试

    soapUI参数中文乱码问题解决方法 可能方案1: 字体不支持中文,将字体修改即可: file-preferences-editor settings-select font 修改字体,改成能显示中文 ...

  4. Spring Boot 、mybatis 、swagger 和 c3p0 整合

    文件路径如下 添加依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...

  5. MVC知识记录

    1.完整深入分析 MVC请求机制:http://blog.jobbole.com/85033/ 2.MVC入门:http://www.aizhengli.com/givecase-aspnet-5-m ...

  6. scala 排序

    sortBy() 定义: def sortBy[B](fun: (A) =>B) 栗子1: val words = "the quick brown fox jumped over t ...

  7. Zookeeper 源码(七)请求处理

    Zookeeper 源码(七)请求处理 以单机启动为例讲解 Zookeeper 是如何处理请求的.先回顾一下单机时的请求处理链. // 单机包含 3 个请求链:PrepRequestProcessor ...

  8. C#使用互斥量(Mutex)实现多进程并发操作时多进程间线程同步操作(进程同步)的简单示例代码及使用方法

    本文主要是实现操作系统级别的多进程间线程同步(进程同步)的示例代码及测试结果.代码经过测试,可供参考,也可直接使用. 承接上一篇博客的业务场景[C#使用读写锁三行代码简单解决多线程并发写入文件时线程同 ...

  9. jquery从零开始学----选择器

     (2011-01-10 21:21:28) 转载▼ 后代选择器: $("mix mix"),当然可以是多个嵌套,但后代选择器可以是深层子代,所以$("mix mix m ...

  10. jfinal框架教程

    jfinal框架教程 下面通过一个小例子了解jfinal的结构和特点 1.建数据库(我用的是oracle数据库,其他的相对也差不多) -- Create table create table CLAS ...