上一篇对查询按照简单查询、条件查询、聚合查询进行了分类,并逐一介绍了基本用法。正则表达式
本文对条件查询再进行分类,介绍子条件查询和复合条件查询。json
子条件查询:特定字段查询 所指特定值。app
复合条件查询:以必定的逻辑 组合 子条件查询。ide
子条件查询又分为:Query context 和 Filter Context。ui
在查询过程当中,除了判断文档是否知足查询条件外,ES还为计算一个_score来标识匹配的程度,旨在判断目标文档和查询条件匹配的有多好。spa
Query context 经常使用的查询包括:.net
全文本查询:针对文本类型的数据code
字段级别的查询:针对结构化的数据,好比数字、日期等orm
说了这么多概念,画个树吧:blog
全文本查询 包括:模糊匹配、习语匹配、多个字段的匹配查询、语法的查询。
下面,咱们在上一篇文章录入的的索引和文档的基础上继续进行查询。具体的索引结构和文档数据请翻看上一篇文章。
咱们建立了一个rent索引,一个community类型,以及对应的18个文档。
示例数据是以前写的文章里的,这里不在累述,我把索引定义给出:
{ "state": "open", "settings": { "index": { "creation_date": "1523632189666", "number_of_shards": "3", "number_of_replicas": "1", "uuid": "lUrZ_KHtQcuG33MFNivX-A", "version": { "created": "5060899" }, "provided_name": "rent" } }, "mappings": { "community": { "properties": { "creationdate": { "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis", "type": "date" }, "city": { "type": "keyword" }, "communityname": { "type": "text" }, "age": { "type": "integer" } } }, "shop": { } }, "aliases": [ ], "primary_terms": { "0": 2, "1": 2, "2": 2 }, "in_sync_allocations": { "0": [ "0RFsy8yXT6WM25oL8n5gew" , "QfWzYOCWQYy_QISycd-PNg" ], "1": [ "MBaaq2YfQRmrR1hZx6qqhQ" , "iIxY5sN8Q3m6CR4Q5TxzXw" ], "2": [ "vEbuzvxzTW2y_mokZWQSig" , "VhIOetKsSDqeOnG3HisH_w" ] } }
(本文出自oschina博主happybks的博文:https://my.oschina.net/happyBKs/blog/1799387)
模糊匹配,使用match关键词,对文本类型字段进行匹配时,会按照条件值中的各个字或者说分词进行匹配。
POST http://localhost:9200/rent/community/_search
{ "query":{ "match":{ "communityname":"中海万锦城(二期)" } } }
结果除了包含中海万锦城(二期)、包括其余communityname字段包含“中”“海”“万”等字的文档。
由于这是模糊匹配,彻底同样的、包含中海的、包含一个万字文档,匹配的程度不一样,_score的分数也不一样。返回结果按照匹配度,即_score分数由高到低(可是_score大于0,若等于0表示彻底不匹配就不会被模糊查询到)排列。
查询结果
{ "took": 253, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 11, "max_score": 10.104993, "hits": [ { "_index": "rent", "_type": "community", "_id": "AWLZGp3aoILHeA4gRvWM", "_score": 10.104993, "_source": { "communityname": "中海万锦城(二期)", "city": "上海闸北不夜城", "age": 6, "creationdate": "2012-01-01" } }, { "_index": "rent", "_type": "community", "_id": "AWLZGbCzoILHeA4gRvWL", "_score": 3.335333, "_source": { "communityname": "中海悦府", "city": "上海松江泗泾", "age": 4, "creationdate": "2014-01-01" } }, { "_index": "rent", "_type": "community", "_id": "AWLZHR2loILHeA4gRvWN", "_score": 2.0010364, "_source": { "communityname": "中海紫御豪庭", "city": "上海普陀长征", "age": 6, "creationdate": "2012-01-01" } }, { "_index": "rent", "_type": "community", "_id": "AWLZHsN6oILHeA4gRvWO", "_score": 1.6676666, "_source": { "communityname": "象屿鼎城", "city": "上海浦东川沙", "age": 5, "creationdate": "2013-01-01" } }, { "_index": "rent", "_type": "community", "_id": "AWLZDcK7oILHeA4gRvWB", "_score": 1.2871116, "_source": { "communityname": "万科蓝山", "city": "上海浦东曹路", "age": 14, "creationdate": "2004-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZCaoSoILHeA4gRvV-", "_score": 0.91251767, "_source": { "communityname": "万科朗润园", "city": "上海", "age": 12, "creationdate": "2006-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZEXNioILHeA4gRvWD", "_score": 0.7981695, "_source": { "communityname": "万科白马花园", "city": "上海莘闵别墅区", "age": 15, "creationdate": "2003-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZC1HYoILHeA4gRvV_", "_score": 0.7981695, "_source": { "communityname": "万科优诗美地", "city": "上海闵行七宝", "age": 19, "creationdate": "1999-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLY7wnkoILHeA4gRvV8", "_score": 0.36413702, "_source": { "communityname": "万科阳光苑", "city": "上海", "age": 10, "creationdate": "2008-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZDK3-oILHeA4gRvWA", "_score": 0.36413702, "_source": { "communityname": "万科清林径", "city": "上海浦东新区新场镇", "age": 6, "creationdate": "2012-01-01 00:00:00" } } ] } }
若是你但愿将查询条件中的值做为一个固定的习语进行匹配,而不是根据匹配程度进行模糊匹配,可使用习语匹配。关键词是match_phrase
POST http://localhost:9200/rent/community/_search
{ "query":{ "match_phrase":{ "communityname":"中海万锦城(二期)" } } }
查询结果:
此时查询结果咱们发现只一条了。
{ "took": 568, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 10.104993, "hits": [ { "_index": "rent", "_type": "community", "_id": "AWLZGp3aoILHeA4gRvWM", "_score": 10.104993, "_source": { "communityname": "中海万锦城(二期)", "city": "上海闸北不夜城", "age": 6, "creationdate": "2012-01-01" } } ] } }
多个字段的模糊匹配查询 须要用到关键词multi_match,而后里面套query和fields关键词,指明查询条件文本和须要匹配哪些字段。
POST http://localhost:9200/rent/community/_search
{ "query":{ "multi_match":{ "query":"山江", "fields":["communityname","city"] } } }
查询结果:
能够看到小区名称或者地址信息中包含“山”或“江”的小区文档都被模糊匹配查询到了。
{ "took": 17, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 4, "max_score": 1.7792181, "hits": [ { "_index": "rent", "_type": "community", "_id": "AWLZEy0foILHeA4gRvWE", "_score": 1.7792181, "_source": { "communityname": "金地艺境(宝山)", "city": "上海宝山区", "age": 6, "creationdate": "2012-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLDhHMpoILHeA4gRvV7", "_score": 1.7792181, "_source": { "communityname": "世茂滨江花园", "city": "上海", "age": 9, "creationdate": "2009-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZDcK7oILHeA4gRvWB", "_score": 1.2871116, "_source": { "communityname": "万科蓝山", "city": "上海浦东曹路", "age": 14, "creationdate": "2004-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZFA5EoILHeA4gRvWF", "_score": 1.0751344, "_source": { "communityname": "金地艺境(松江)", "city": "上海松江区", "age": 3, "creationdate": "2015-01-01 00:00:00" } } ] } }
所谓语法查询,就是根据必定的语法规则进行的查询。常常在Kibana中用,是作数据搜索用的,支持通配符、范围查询、布尔查询、正则表达式等。语法十分丰富。关键词query_string。
有多个条件能够用逻辑与,关键词AND
POST http://localhost:9200/rent/community/_search
{ "query":{ "query_string":{ "query":"万科 AND 大道" } } }
结果:
{ "took": 386, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 2.9101574, "hits": [ { "_index": "rent", "_type": "community", "_id": "AWLZD_9YoILHeA4gRvWC", "_score": 2.9101574, "_source": { "communityname": "万科公园大道", "city": "上海老闵行", "age": 3, "creationdate": "2015-01-01 00:00:00" } } ] } }
若是是逻辑或,关键词OR。而且,语法条件能够组合。
POST http://localhost:9200/rent/community/_search
{ "query":{ "query_string":{ "query":"(万科 AND 大道) OR 象屿" } } }
结果:
{ "took": 324, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 2, "max_score": 4.0250216, "hits": [ { "_index": "rent", "_type": "community", "_id": "AWLZHsN6oILHeA4gRvWO", "_score": 4.0250216, "_source": { "communityname": "象屿鼎城", "city": "上海浦东川沙", "age": 5, "creationdate": "2013-01-01" } }, { "_index": "rent", "_type": "community", "_id": "AWLZD_9YoILHeA4gRvWC", "_score": 2.9101574, "_source": { "communityname": "万科公园大道", "city": "上海老闵行", "age": 3, "creationdate": "2015-01-01 00:00:00" } } ] } }
这个和多字段模糊匹配时的关键词同样,须要用到fields关键词,而后在列表里把所涉及的字段名称给出。
POST http://localhost:9200/rent/community/_search
{ "query":{ "query_string":{ "query":"公园 OR 闵行", "fields":["communityname","city"] } } }
查询结果:
{ "took": 53, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 4, "max_score": 2.1502688, "hits": [ { "_index": "rent", "_type": "community", "_id": "AWLZD_9YoILHeA4gRvWC", "_score": 2.1502688, "_source": { "communityname": "万科公园大道", "city": "上海老闵行", "age": 3, "creationdate": "2015-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZCaoSoILHeA4gRvV-", "_score": 1.1690899, "_source": { "communityname": "万科朗润园", "city": "上海", "age": 12, "creationdate": "2006-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZEXNioILHeA4gRvWD", "_score": 1.0225905, "_source": { "communityname": "万科白马花园", "city": "上海莘闵别墅区", "age": 15, "creationdate": "2003-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLDhHMpoILHeA4gRvV7", "_score": 1.0225905, "_source": { "communityname": "世茂滨江花园", "city": "上海", "age": 9, "creationdate": "2009-01-01 00:00:00" } } ] } }
字段级别的查询,或者说结构化查询,在query下的关键词须要用term。
好比查询房龄为10年的小区:
POST http://localhost:9200/rent/community/_search
{ "query":{ "term":{ "age":10 } } }
结果:
{ "took": 197, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 2, "max_score": 1, "hits": [ { "_index": "rent", "_type": "community", "_id": "AWLY7wnkoILHeA4gRvV8", "_score": 1, "_source": { "communityname": "万科阳光苑", "city": "上海", "age": 10, "creationdate": "2008-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZF4FAoILHeA4gRvWI", "_score": 1, "_source": { "communityname": "保利西子湾", "city": "上海松江大学城", "age": 10, "creationdate": "2008-01-01" } } ] } }
这时,咱们尝试像以前模糊匹配的示例那样在字段级别查询里查询“万科”
注意:关键词是字段级别查询的关键词term。
POST http://localhost:9200/rent/community/_search
{ "query":{ "term":{ "communityname":"万科" } } }
结果,发现查询结果的数量是0。而以前用match作全文本查询时,查询“万科”,会获得一大推communityname的值中包含“万”或“科”字的文档。
{ "took": 14, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 0, "max_score": null, "hits": [] } }
那咱们在尝试一下输入完整的字段值。若是咱们将term中条件communityname字段的值设置为一个彻底存在的值,例如:万科公园大道
{ "query":{ "term":{ "communityname": "万科公园大道" } } }
结果发现,依然没有返回结果。由于commmunityname字段是text文本类型。不适用于字段级别的查询。
若是咱们换成city字段,就没有问题:
{ "query":{ "term":{ "city": "上海老闵行" } } }
结果,返回了对应的结果,由于city字段是keyword类型:
{ "took": 10, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 1.2039728, "hits": [ { "_index": "rent", "_type": "community", "_id": "AWLZD_9YoILHeA4gRvWC", "_score": 1.2039728, "_source": { "communityname": "万科公园大道", "city": "上海老闵行", "age": 3, "creationdate": "2015-01-01 00:00:00" } } ] } }
字段级别的查询,还能够查询特定字段必定范围值内的文档有哪些。这种涉及字段值范围的条件,须要用到关键词range。范围描述的关键词与mongo中的十分相似。
关键词 | 含义 | 数学符号 |
gt | 大于 | > ( |
gte | 大于等于 | ≥ [ |
lt | 小于 | < ) |
lte | 小于等于 | ≤ ] |
咱们来查一下,房龄在5到7年(含5年,不含7年)的小区有哪些:age的字段类型是integer
{ "query":{ "range":{ "age": { "gte":5, "lt":7 } } } }
查询结果:
{ "took": 11, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 6, "max_score": 1, "hits": [ { "_index": "rent", "_type": "community", "_id": "AWLZDK3-oILHeA4gRvWA", "_score": 1, "_source": { "communityname": "万科清林径", "city": "上海浦东新区新场镇", "age": 6, "creationdate": "2012-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZGp3aoILHeA4gRvWM", "_score": 1, "_source": { "communityname": "中海万锦城(二期)", "city": "上海闸北不夜城", "age": 6, "creationdate": "2012-01-01" } }, { "_index": "rent", "_type": "community", "_id": "AWLZEy0foILHeA4gRvWE", "_score": 1, "_source": { "communityname": "金地艺境(宝山)", "city": "上海宝山区", "age": 6, "creationdate": "2012-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZHsN6oILHeA4gRvWO", "_score": 1, "_source": { "communityname": "象屿鼎城", "city": "上海浦东川沙", "age": 5, "creationdate": "2013-01-01" } }, { "_index": "rent", "_type": "community", "_id": "AWLZFV2doILHeA4gRvWG", "_score": 1, "_source": { "communityname": "金地艺华年", "city": "上海浦东航头", "age": 5, "creationdate": "2013-01-01" } }, { "_index": "rent", "_type": "community", "_id": "AWLZHR2loILHeA4gRvWN", "_score": 1, "_source": { "communityname": "中海紫御豪庭", "city": "上海普陀长征", "age": 6, "creationdate": "2012-01-01" } } ] } }
字段级别的范围查询同时还支持日期类型:
(字段级别查询:“看吧,全部类型我都支持,我就不支持你文本text类型,谁让你和全文本类型打得火热”)
POST http://localhost:9200/rent/community/_search
{ "query":{ "range":{ "creationdate": { "gte":"2011-12-31", "lt":"2014-01-01" } } } }
返回结果:
{ "took": 358, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 6, "max_score": 1, "hits": [ { "_index": "rent", "_type": "community", "_id": "AWLZDK3-oILHeA4gRvWA", "_score": 1, "_source": { "communityname": "万科清林径", "city": "上海浦东新区新场镇", "age": 6, "creationdate": "2012-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZGp3aoILHeA4gRvWM", "_score": 1, "_source": { "communityname": "中海万锦城(二期)", "city": "上海闸北不夜城", "age": 6, "creationdate": "2012-01-01" } }, { "_index": "rent", "_type": "community", "_id": "AWLZEy0foILHeA4gRvWE", "_score": 1, "_source": { "communityname": "金地艺境(宝山)", "city": "上海宝山区", "age": 6, "creationdate": "2012-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZHsN6oILHeA4gRvWO", "_score": 1, "_source": { "communityname": "象屿鼎城", "city": "上海浦东川沙", "age": 5, "creationdate": "2013-01-01" } }, { "_index": "rent", "_type": "community", "_id": "AWLZFV2doILHeA4gRvWG", "_score": 1, "_source": { "communityname": "金地艺华年", "city": "上海浦东航头", "age": 5, "creationdate": "2013-01-01" } }, { "_index": "rent", "_type": "community", "_id": "AWLZHR2loILHeA4gRvWN", "_score": 1, "_source": { "communityname": "中海紫御豪庭", "city": "上海普陀长征", "age": 6, "creationdate": "2012-01-01" } } ] } }
若是要表示如今,可使用关键词now。
好比查询2015年至今的新小区:
POST http://localhost:9200/rent/community/_search
{ "query":{ "range":{ "creationdate": { "gte":"2015-01-01", "lt":"now" } } } }
结果:
{ "took": 80, "timed_out": false, "_shards": { "total": 3, "successful": 3, "skipped": 0, "failed": 0 }, "hits": { "total": 3, "max_score": 1, "hits": [ { "_index": "rent", "_type": "community", "_id": "AWLZD_9YoILHeA4gRvWC", "_score": 1, "_source": { "communityname": "万科公园大道", "city": "上海老闵行", "age": 3, "creationdate": "2015-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZFA5EoILHeA4gRvWF", "_score": 1, "_source": { "communityname": "金地艺境(松江)", "city": "上海松江区", "age": 3, "creationdate": "2015-01-01 00:00:00" } }, { "_index": "rent", "_type": "community", "_id": "AWLZGGD2oILHeA4gRvWJ", "_score": 1, "_source": { "communityname": "保利艾庐", "city": "上海浦东新区周浦镇", "age": 3, "creationdate": "2015-01-01" } } ] } }