关于全文搜索elastic search matchsearch中matchQuery和termQuery的区别

ElasticSearch 导入数据的一个坑,肯定不止我一人中招
· Ruby China
今天使用 ES 时,碰到一个坑,估计其他同学或许也会碰到,特此分享一下。
step 1 Model
BetOrder 是一个订单的 model,搜索时我打算使用 term query。我把 mapping 设置为
index: 'not_analyzer' ,故意不分词,以便精确搜索。
Gem 用的是
# model/bet_order.rb
# Set up index configuration and mapping
# Searching tokens exactly
settings do
mappings do
indexes :title,
index: 'not_analyzed'
indexes :nickname,
index: 'not_analyzed'
indexes :user_key,
index: 'not_analyzed'
indexes :out_trade_no, index: 'not_analyzed'
indexes :trade_no,
index: 'not_analyzed'
indexes :buyer_email,
index: 'not_analyzed'
step 2 导入数据
BetOrder.import
step3 悲剧了,导入数据后 mapping 不对
然后是debug 呀,debug。。。。。
翻来覆去的找,没找到原因,最后去翻了翻 elasticsearch-rails 的源码,原来导入数据的时候需要加上参数 force: true,才会根据 mapping 创建索引。
BetOrder.import force:true
源码地址:
问题解决,上一个正常 mapping
顺便请教一个问题:为什么第一次 import 数据时,作者不根据 model 中定义的 mapping 创建。这算不算一个bug?
昨天也遇到这个, 这应该算是文档没写清楚吧 , 我学得按照model定义创建 mapping。另外,想请教下有没有用中文分词,用的哪个?谢谢
可以先BetOrder.elasticsearch.create_index!来创建索引,这个时候会按照map来配置。然后可以index各个document。
直接导入没有具体测试,确定import前没有建立index mapping哦。
model里面我是直接用
mapping do
settings do
mappings do
不知具体什么区别?
我测过了,直接 import 时创建的 mapping 是错误的。
中文分词我用的 mmseg_analyzer,效果还不错。
分词以前一直用mmseg,从sphinx到es。不过最近代码里面产品只需要sql like的程度就够,还没有去配置分词。
这个问题之前我也遇到过,还是得读源码。另外使用ik进行处理性能不高,会出现HTTP timeout。后来换成mmseg了。
问下,mapping时比如标签列表tags: [''abc','def']去存储,
当index not_analyzed时候,可以用filter查询查找到
当默认string analyzed时候,可以query match来,这个时候用filter搜索不到
如何让他可以filter又可以在搜索时候被match到,是怎么mapping的
我也被坑了,3q
后方可回复, 如果你还没有账号请点击这里 。
共收到 8 条回复下次自动登录
现在的位置:
& 综合 & 正文
分布式搜索Elasticsearch——QueryBuilders.matchPhraseQuery
注:该文项目基础为分布式搜索和,项目骨架可至下载。
ES源代码中对matchPhraseQuery的描述如下所示:
* Creates a text query with type "PHRASE" for the provided field name and text.
* @param name The field name.
* @param text The query text (to be analyzed).
public static MatchQueryBuilder matchPhraseQuery(String name, Object text) {
return new MatchQueryBuilder(name, text).type(MatchQueryBuilder.Type.PHRASE);
先看示例:
* @author Geloin
package com.geloin.esample.
import java.util.UUID;
import junit.framework.A
import org.elasticsearch.action.bulk.BulkRequestB
import org.elasticsearch.action.bulk.BulkR
import org.elasticsearch.action.index.IndexR
import org.elasticsearch.action.search.SearchR
import org.elasticsearch.index.query.QueryB
import org.elasticsearch.index.query.QueryB
import org.elasticsearch.search.SearchH
import org.elasticsearch.search.SearchH
import org.junit.T
import com.geloin.esample.BaseT
import com.geloin.esample.entity.P
* @author Geloin
public class MatchPhraseQueryTest extends BaseTest {
public void matchPhraseQuery() {
// 创建索引
BulkRequestBuilder builder = client.prepareBulk();
for (int i = 0; i & 5; i++) {
Person p = new Person();
p.setId(UUID.randomUUID().toString());
p.setAge(20);
p.setIsStudent(false);
p.setSex("男");
p.setName("小别克听老别克讲别克的故事");
String source = ElasticSearchUtil.BeanToJson(p);
IndexRequest request = client.prepareIndex().setIndex(index)
.setType(type).setId(p.getId()).setSource(source)
.request();
builder.add(request);
BulkResponse bResponse = builder.execute().actionGet();
if (bResponse.hasFailures()) {
Assert.fail("创建索引出错!");
QueryBuilder qb = QueryBuilders.matchPhraseQuery("name", "小别克老");
SearchResponse searchResponse = client.prepareSearch(index)
.setTypes(type).setQuery(qb).setFrom(0).setSize(12)
.execute().actionGet();
SearchHits hits = searchResponse.getHits();
if (null == hits || hits.totalHits() == 0) {
log.error("使用\"小别克老\"没有查询到任何结果!");
for (SearchHit hit : hits) {
String json = hit.getSourceAsString();
Person newPerson = mapper.readValue(json, Person.class);
System.out.println("name\t\t" + newPerson.getName());
System.out.println("sex\t\t" + newPerson.getSex());
System.out.println("age\t\t" + newPerson.getAge());
System.out.println("isStudent\t\t"
+ newPerson.getIsStudent());
QueryBuilder qb1 = QueryBuilders.matchPhraseQuery("name", "小别克听");
SearchResponse searchResponse1 = client.prepareSearch(index)
.setTypes(type).setQuery(qb1).setFrom(0).setSize(12)
.execute().actionGet();
SearchHits hits1 = searchResponse1.getHits();
if (null == hits1 || hits1.totalHits() == 0) {
log.error("使用\"小别克听\"没有查询到任何结果!");
for (SearchHit hit : hits1) {
String json = hit.getSourceAsString();
Person newPerson = mapper.readValue(json, Person.class);
System.out.println("name\t\t" + newPerson.getName());
System.out.println("sex\t\t" + newPerson.getSex());
System.out.println("age\t\t" + newPerson.getAge());
System.out.println("isStudent\t\t"
+ newPerson.getIsStudent());
Thread.sleep(1000000);
} catch (Exception e) {
e.printStackTrace();
你会发现,使用“小别克老”没有查询出任何结果,而使用“小别克听”则查询出了我们需要的结果,这便是matchPhraseQuery和matchQuery等的区别,在使用matchQuery等时,即使你传入的是“小别克老”,在执行查询时,“小别克老”会被分词器分词,例如paoding解析成“小别/别克/老”,而使用matchPhraseQuery时,“小别克老”并不会被分词器分词,而是直接以一个短语的形式查询,而如果你在创建索引所使用的field的value中没有这么一个短语(顺序无差,且连接在一起),那么将查询不出任何结果。
&&&&推荐文章:
【上篇】【下篇】标签:至少1个,最多5个
query与filter的合并
将filter的api列为deprecated,然后合并到query里头。之后查询的context就分为query的context和filter的context。凡是不是filter的context就走query的context。filter的话,其结果不参与score计算,而且会缓存,可能相对快一些。
判断是否属于filter context
the constant_score query
the must_not and (newly added) filter parameter in the bool query
the filter and filters parameters in the function_score query
any API called filter, such as the post_filter search parameter, or in aggregations or index aliases
deprecated的方式
"query": {
"filtered": {
"filter": {
"year": 1961
合并后的方式
"query": {
"filter": {
"status": "active"
bool的话,这种方式出来的score为0,如果加上个match_all的话,则score为1
"query": {
"match_all": {}
"filter": {
"status": "active"
constant_score方式
"query": {
"constant_score": {
"filter": {
"status": "active"
constant_score的方式,默认score为1
match和term query的区别
matchQuery的机制是:先检查字段类型是否是analyzed,如果是,则先分词,再去去匹配token;如果不是,则直接去匹配token。
termQuery的机制是:直接去匹配token。
对于value中带-的特殊处理
"query": {
"filter": {
"status": "demo-active"
value带了-,则默认会被切词,导致搜索结果不准确。解决办法之一就是在字段那里加个.raw
"query": {
"filter": {
"status.raw": "demo-active"
关于合并后的filter在java api中的使用
使用json最直接,省得再用java的api翻译一遍
String queryJson = "{\n" +
\"query\": {\n" +
\"constant_score\": {\n" +
\"filter\": {\n" +
\"term\": {\n" +
\"status.raw\": \"demo-active\"\n" +
QueryBuilders.wrapperQuery(queryJson)
[在elasticsearch里如何高效的使用filter [性能优化必看]](
0 收藏&&|&&0
你可能感兴趣的文章
6 收藏,2.3k
5 收藏,1.1k
本作品采用 署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可
分享到微博?
技术专栏,帮你记录编程中的点滴,提升你对技术的理解收藏感兴趣的文章,丰富自己的知识库
明天提醒我
我要该,理由是:
扫扫下载 App}

我要回帖

更多关于 elastic match type 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信