NEST 基础使用
1. 建立连接,创建 client
var nodes = new[]
{
new Uri("http://localhost:9200")
};
var pool = new StaticConnectionPool(nodes);
var settings = new ConnectionSettings(pool); ;
var client = new ElasticClient(settings);
2.获取所有索引
var indexs = client.Cat.Indices();
3. 创建一个索引
- 可以增加多个 map 之类,多个之类相当于属性拼成了一个大表
- subClass1 与 subClass2 之间如果有重复名称的字段,那么先 map 的会保留,后续的不会覆盖前面的同名字段 —— 如下例:先 map 的 Company,后 map 的 Employee,那么生成 index 的时候,实际生成的是 Company
的 字段, 也就是 string 类型的 Name
client.Indices.Create("indexTest1", c => c
.Map(m => m
.AutoMap<Company>()
.AutoMap<Employee>()
)
);
public abstract class Document
{
public JoinField Join { get; set; }
}
public class Company : Document
{
public string Name { get; set; }
public List<Employee> Employees { get; set; }
}
public class Employee : Document
{
public int Name { get; set; }
public int Salary { get; set; }
public DateTime Birthday { get; set; }
public bool IsManager { get; set; }
public List<Employee> Employees { get; set; }
public TimeSpan Hours { get; set; }
}
4. 给 Es 的对象加上对应的解析特性
- 类似 JsonProperty 那种,在创建索引的时候,或者查询数据的时候,NEST 可以根据 Attribute 来解析 —— 相应的对应类型说明https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/auto-map.html
[ElasticsearchType(RelationName = "employee")]
public class Employee
{
[Text(Name = "first_name", Norms = false, Similarity = "LMDirichlet")]
public string FirstName { get; set; }
[Text(Name = "last_name")]
public string LastName { get; set; }
[Number(DocValues = false, IgnoreMalformed = true, Coerce = true)]
public int Salary { get; set; }
[Date(Format = "MMddyyyy")]
public DateTime Birthday { get; set; }
[Boolean(NullValue = false, Store = true)]
public bool IsManager { get; set; }
[Nested]
[PropertyName("empl")]
public List<Employee> Employees { get; set; }
[Text(Name = "office_hours")]
public TimeSpan? OfficeHours { get; set; }
[Object]
public List<Skill> Skills { get; set; }
}
public class Skill
{
[Text]
public string Name { get; set; }
[Number(NumberType.Byte, Name = "level")]
public int Proficiency { get; set; }
}
5. 查询
- 最简单的查询示例
var qr1 = client.Search<NodeLogSearchEntity>(s => s .Index("log.test_mix-2021.01.18") .Query(q => q .MatchAll() ) );
- 较为复杂的查询
var result = client.Search<VendorPriceInfo>( s => s .Explain() //参数可以提供查询的更多详情。 .FielddataFields(fs => fs //对指定字段进行分析 .Field(p => p.vendorFullName) .Field(p => p.cbName) ) .From(0) //跳过的数据个数 .Size(50) //返回数据个数 .Query(q => q.Term(p => p.vendorID, 100) // 主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed 的字符串(未经分析的文本数据类型): && q.Term(p => p.vendorName.Suffix("temp"), "姓名") //用于自定义属性的查询 (定义方法查看 MappingDemo) && q.Bool( //bool 查询 b => b .Must(mt => mt //所有分句必须全部匹配,与 AND 相同 .TermRange(p => p.Field(f => f.priceID).GreaterThan("0").LessThan("1"))) //指定范围查找 .Should(sd => sd //至少有一个分句匹配,与 OR 相同 .Term(p => p.priceID, 32915), sd => sd.Terms(t => t.Field(fd => fd.priceID).Terms(new[] {10, 20, 30})),//多值 //|| //sd.Term(p => p.priceID, 1001) //|| //sd.Term(p => p.priceID, 1005) sd => sd.TermRange(tr => tr.GreaterThan("10").LessThan("12").Field(f => f.vendorPrice)) ) .MustNot(mn => mn//所有分句都必须不匹配,与 NOT 相同 .Term(p => p.priceID, 1001) , mn => mn.Bool( bb=>bb.Must(mt=>mt .Match(mc=>mc.Field(fd=>fd.carName).Query("至尊")) )) ) ) )//查询条件 .Sort(st => st.Ascending(asc => asc.vendorPrice))//排序 .Source(sc => sc.Include(ic => ic .Fields( fd => fd.vendorName, fd => fd.vendorID, fd => fd.priceID, fd => fd.vendorPrice))) //返回特定的字段 );
二、Elasticsearch 的文本的查询
es 的 text 数据存储,实际上插入一条数据的时候,会默认的分词,分词后再倒排索引,后面方便查询。text 在被 index 的时候,会保留一个它的子字段 text.keyword,改字段是不被分词的 text 字段。(ps: map 的时候也可以设置不分析)
0. 查看一个 text 的分析
- 在 kibana 里面的 devtool 里面执行即可
POST _analyze { "analyzer": "standard", "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone." }
1. 精准匹配
属性 查询之 key
分词的查询 json查询之 key
不分词的查询 jsones 中数据 => 分词 { "query": { "match": { "key": "value" } } }
{ "query": { "term": { "key": "value" } } }
es 中数据 => 不分词 { "query": { "match": { "key.keyword": "value" } } }
{ "query": { "term": { "key.keyword": "value" } } }
2. 模糊匹配 —— 字符串 Levenshtein distance =》 fuzzy
fuzzy 匹配是根据 Levenshtein distance 来判断是否匹配,一般长度为 0,1,2 太大将不会匹配,因为结果太多了
- eg: cat,kat,他们就一个字符不同所以 Levenshtein distance(“kat”,”cat”) = 1
属性 fuzzy 的 key
的查询 jsones 中数据 => 分词 { "query": { "fuzzy": { "key": { "value": "cat" "fuzziness": "1" } } } }
es 中数据 => 不分词 { "query": { "fuzzy": { "key.keyword": { "value": "cat" "fuzziness": "1" } } } }
3. 模糊匹配 —— 使用通配符 wildcard 匹配 =》 WildCard
WildCard 匹配 就很像我们 SQL 里面的 like 匹配 只不过这里使用 *或者? 来匹配
- eg: kiy, kity, kimchy 加入要匹配这三个
属性 fuzzy 的 key
的查询 jsones 中数据 => 分词 { "query": { "wildcard": { "key": { "value": "ki*y" } } } }
es 中数据 => 不分词 { "query": { "wildcard": { "key.keyword": { "value": "ki*y" } } } }
来源:https://www.jianshu.com/p/c3d15fbfec36
© 版权声明
博主的文章没有高度、深度和广度,只是凑字数。利用读书、参考、引用、抄袭、复制和粘贴等多种方式打造成自己的纯镀 24k 文章!如若有侵权,请联系博主删除。
喜欢就点个赞吧