MyBlog


ES总结四:检索

<p>[TOC]</p> <h1>全文查询</h1> <h2>match</h2> <p>举一个例子,比如说存在某文档标题为:java编程思想。如果使用term query查询‘java编程思想’,查不到匹配性。因为term查询的是词项,java编程思想分词后会变成java、编程,思想、等词,所以Java编程思想查询不到,相反的是有match query 查询 java编程思想就可以查询的到。match会对查询语句进行分词,分词后查询语句中的任何一个词项被匹配,文档就会被搜索到。</p> <h2>match_phrase</h2> <p>match_phrase首先会把query内容分词,分词器可以自定义,同时文档还要满足以下两个条件才会被搜索到 1)分词后所有词项都要出现在该字段中。 (2)字段中的词项顺序要一致 <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/21614596c425a4260bc58fdb2b569f2a?showdoc=.jpg" alt="" /></p> <h2>match_phrase_prefix</h2> <p>match_phrase_prefix和match_phrase类似,只不过match_phrase_prefix支持最后一个term前缀匹配: <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/44cab74a09b435129412a3e3209a50ca?showdoc=.jpg" alt="" /></p> <h2>multi_match</h2> <p>multi_match是match的升级,用于搜索多个字段.。</p> <h2>query_string</h2> <p>querystringquery是与Lucene查询语句的语法结合非常紧密的一种查询,允许在一个查询语句中使用多个特殊条件关键字(如:AND|OR|NOT)对多个字段进行查询,建议熟悉Lucene查询语法的用户去使用.</p> <h2>simple_query_string</h2> <p>simple_query_string是一种适合直接暴露给用户,并且具有非常完善的查询语法的查询语句,接受Lucene查询语法,解析过程中发生错误不会抛出异常</p> <h1>词项查询</h1> <p>全文搜索在执行查询之前会分析查询字符串,词项搜索时对倒排索引中存储的词项进行精确操作。词项级别的查询通常用于结构化数据,如数字、日期和枚举类型。</p> <h2>term</h2> <p>term查询用来查找指定字段中包含给定单词的文档,term查询不被解析,只有查询词和文档中的词精确匹配才会被搜索到,应用场景为查询人名、地名等需要精准配备的需求。</p> <h2>terms</h2> <p>字段中包含关键词“java”或“python”的文档,构造查询语句如下: <code>GETbooks/search</code></p> <pre><code class="language-json">{ "query": { "terms": { "title": ["java", "python"] } } }</code></pre> <h2>range</h2> <p>range查询用于匹配在某一范围内的数值型、日期类型或者字符串型字段的文档,比如搜索哪些书籍的价格在50到100之间、哪些书籍的出版时间在2014年到2016年之间。使用range查询只能查询一个字段,不能作用在多个字段上。range查询支持的参数有以下几种: •gt大于,查询范围的最小值,也就是下界,但是不包含临界值。 •gte大于等于,和gt的区别在于包含临界值。 •It小于,查询范围的最大值,也就是上界,但是不包含临界值。 •lte小于等于,和It的区别在于包含临界值 例如,想要查询价格大于50小于等于70的书籍,即50&lt;price&lt;=70, 构造查询语句如下: <code>GETbooks/search</code></p> <pre><code class="language-json">{ "query": { "range": { "price": { "gt": 50, "lte": 70 } } } }</code></pre> <p>查询出版日期在2016年1月1日和2016年12月31之间的书籍,对publish_time字段进行range查询:</p> <pre><code class="language-json">{ "query": { "range": { "pub1ish_time": { "gte": "2016-01-01", "lte": "2016-12-31", "format": "yyyy-MM-dd" } } } }</code></pre> <h2>exists</h2> <p>exists查询会返回字段中至少有一个非空值的文档</p> <pre><code class="language-json">{ "query": { "exists": { "field": "user" } } }</code></pre> <p>user字段不为空的文档会被匹配出来</p> <h2>prefix</h2> <p>prefix查询用于查询某个字段中以给定前缀开始的文档,比如查询title中含有以java为前缀的关键词的文档,那么含有javajavascriptjavaee等所有以java开头关键词的文档都会被匹配</p> <pre><code class="language-json">{ "query": { "prefix": { "description": "win" } } }</code></pre> <h2>wildcard</h2> <p>假设需要找某一作者写的书,但是忘记了作者名字的全称,只记住了前两个字,那么就可以使用通配符查询:</p> <pre><code class="language-json">{ "query": { "wildcard": { "author": "张三*" } } }</code></pre> <h2>regexp</h2> <p>例如需要匹配以W开头紧跟着数字的邮政编码,使用正则表达式查询构造查询语句如下:</p> <pre><code class="language-json">{ "query": { "regexp": { "postcode": "W[0-9].+" } } }</code></pre> <h2>fuzzy</h2> <p>举例如下,用户在输入查询关键词时不小心把“javascript”拼成“javascritp”,在存在拼写错误的情况下使用模糊查询仍然可以搜索到含有“javascript”的文档,查询语句如下:</p> <pre><code class="language-json">{ "query": { "fuzzy": { "title": "javascritp" } } }</code></pre> <h1>复合查询</h1> <p>复合查询就是把一些简单查询组合在一起实现更复杂的查询需求,除此之外复合查询还可以控制另外一个查询的行为;</p> <h2>constant—score</h2> <p>constant——score query可以包装一个其他类型的查询,并返回匹配过滤器中的查询条件且具有相同评分的文档。下面的查询语句会返回title字段中含有关键词“java”的文档,所有文档的评分都是1.2</p> <pre><code class="language-json">{ "query": { "constantscore": { "filter": { "term": { "title": "java" } }, "boost": 1.2 } } }</code></pre> <h2>bool</h2> <p>bool查询可以把任意多个简单查询组合在一起,使用must、should、must_not、filter选项来表示简单查询之间的逻辑,每个选项都可以出现0次到多次,它们的含义如下:</p> <ul> <li>must:文档必须匹配must选项下的查询条件,相当于逻辑运算的AND</li> <li>should:文档可以匹配should选项下的查询条件也可以不匹配,相当于逻辑运算的OR</li> <li>must_not:与must相反,匹配该选项下的查询条件的文档不会被返回。</li> <li>filter: 和must—样,匹配filter选项下的查询条件的文档才会被返回,但是filter不评分,只起到过滤功能 假设要查询title中包含关键词java,并且price不能高于70,description可以包含也可以不包含虚拟机的书籍,构造bool查询语句如下: <pre><code class="language-json">{ "query": { "bool": { "minimu_should_match": 1, "must": { "match": { "title": "java" } }, "should": [{ "match": { "description": "虚拟机" } }], "must_not ": { "range": { "price": { "gte": 70 } } } } } }</code></pre> <h2>indices</h2> <p>indicesquery适用于需要在多个索引之间进行查询的场景,它允许指定一个索引名字列表和内部查询。indicesquery中有query和nomatchquery两部分,query中用于搜索指定索引列表中的文档,no_match_query中的查询条件用于搜索指定索引列表之外的文档。下面的查询语句实现了搜索索引booksbooks2中title字段包含关键字javascript,其他索引中title字段包含basketball的文档,查询语句如下:</p> <pre><code class="language-json">{ "query": { "indices": { "indices": ["book","book1"], "query":{"match":{"title":"javascript"}}, "no_match_query":{"term":{"title":"basketball"} } } }</code></pre> <h1>其他查询</h1> <p>除了上面讲到的查询之外,ES还有一些其他不常用查询,如嵌套查询、位置查询,特殊查询等等。</p></li> </ul> <h1>搜索排序</h1> <h2>单字段排序</h2> <p>Elasticsearch是按照查询和文档的相关度进行排序的,默认按评分降序排序,搜索title字段中包含java关键词的文档:</p> <pre><code class="language-json">{ "query": { "term": { "title": "java" } } }</code></pre> <p>等价于:</p> <pre><code class="language-json">{ "query": { "term": { "title": "java" } }, "sort": [{ "_score": { "order": "asc" } }] }</code></pre> <p>对于match_all y而言,由于只返回所有文档,不需要评分,<strong>文档的顺序为添加文档的顺序</strong>。如果需要改变match_all的文档返回顺序,可以对_doc进行排序。例如,返回最后添加的那条文档,可以对_doc降序排序,设置返回文档条数为1,命令如下:</p> <pre><code class="language-json">{ "query": { "match_all": {} }, "sort": [{ "_doc": { "order": "desc" } }] }</code></pre> <h2>多字段排序</h2> <p>例如,先按价格降序排序,价格相等的按照出版年份升序排序:</p> <pre><code class="language-json">{ "sort": [{ "price": { "order": "asc" } }, { "year": { "order": "desc" } }] }</code></pre>

页面列表

ITEM_HTML