[ElasticSearch]间隔搜索IntervalsQuery及JavaSDK简单调用

1) 概念

* intervals query 允许用户精确控制查询词在文档中出现的先后关系,实现了对terms顺序、terms之间的距离以及它们之间的包含关系的灵活控制
    通过intervals query(间隔搜索) 我们可以完成各个terms在于不同位置的灵活搜索
    
* 下面来举一个例子来说明间隔搜索的适用场景:
    我们在某个索引中3个包含my_text字段的文档

    文档1:  {"my_text":"curry bad shooter.... "}
    文档2: {"my_text":"curry good shooter....."}
    文档3:  {"my_text":"curry best shooter...."}


    通过间隔搜索,我可以明确的表示 我不想看到curry和shooter之间存在 bad的文档
    我还可以明确的表示,我必须看到curry和shooter之间 存在 某个词 的文档
    我也可以明确的表示,curry必须在best之前等等一系列功能
    
* 例如 我不想看到curry和shooter之间存在bad,DSL如下:
 

{
  "query": {
    "intervals": {
      "content": {
        "match": {
          "query": "curry shooter",
          "ordered": true,
          "filter": {
            "not_containing": {
              "match": {
                "query": "bad"
              }
            }
          }
        }
      }
    }
  }
}

2) 参数

* 首先来看一个略复杂的DSL语句并简单理解后学习参数

POST _search
{
  "query": {
    "intervals" : {
      "my_text" : {
        "all_of" : {
          "ordered" : true,
          "intervals" : [
            {
              "match" : {
                "query" : "stephen curry",
                "max_gaps" : 0,
                "ordered" : true
              }
            },
            {
              "any_of" : {
                "intervals" : [
                  { "match" : { "query" : "best shooter" } },
                  { "match" : { "query" : "cute champion" } }
                ]
              }
            }
          ]
        },
        "boost" : 2.0
      }
    }
  }
}

简单概述上方语句,像包含"stephen curry is best shooter"或者"stephen cuury is cute champion"都会被检索到,但是 "best shooter who is stephen curry" 不会被检索到,因为我们通过ordered参数明确定义了多个intervals的顺序。


你一定看到了all_of并不解,此处简单解释,在某些时候 一个intervals无法满足我们的要求,那么我们可以编写多个intervals,将其放在all_Of内部,表示所有的intervals都要生效,同样内部可以再次嵌套,比如any_of 表示内部的多个intervals只需满足其一即可。

  • match

参数描述
query用户查询的字符串
max_gaps字符串中多个词之间的的最大词间距,超过最大间距的将不会被检索到;默认值是-1,即无距离限制,设置为0的话,query中的字符串必须彼此相连不能拆分
orderedquery中的字符串是否需要有序显示,默认值是false,即不考虑先后顺序,该参数推荐为true,手动控制词间位置顺序
analyzer对query参数中的字符串使用什么分词器,默认使用mapping时该field配置的 search_analyzer
filterintervals独有的过滤语法,下方有说明
  • all_of

参数描述
intervals一个interval集合,集合里面的所有match需要同时在一个文档数据上同时满足才行
max_gaps多个interval查询在一个文档中允许的最大间距,超过最大间距的将不会被检索到;默认值是-1,即不限制,设置为0的话,所有的interval query必须彼此相连不能拆分
ordered配置 intervals 出现的先后顺序,默认值false
filterintervals独有的过滤语法,下方有说明
  • any_of

参数描述
intervals一个interval集合,集合中只需满足其一即可
filterintervals独有的过滤语法,下方有说明
  • filter

在例子中我们提到filter,通过filter和intervals设定的规则可以过滤掉一些我们不想要的间隔词汇的文档,当然filter不仅仅只包含not_contaning参数
     常用的filter参数,如下:
参数描述
containinginterval query中terms之间需要包含filter中的terms
contained_byinterval query中的字符串需要被包含在filter query的terms里
not_containingcontaining 对立面
not_contained_by(比较模糊,有心得的小伙伴可以私信我)contained_by 对立面

此处比较建议使用 containing和not_containing,而不建议使用contained_by和not_contained_by

我们更愿意在query中输入想查询的词条 在fitler中过滤。

  • script filters

如果上面filters语句不能满足你的需求,那么可以尝试一下script filter ,它提供了一个interval变量,通过start、end、gaps三个函数更加灵活的控制term在文本中的顺序与距离:
* 例如下方语句简单解释一下:

POST _search
{
  "query": {
    "intervals": {
      "content": {
        "match": {
          "query": "curry shooter",
          "filter": {
            "script": {
              "source": "interval.start >= 2 && interval.end < 5 && interval.gaps == 1"
            }
          }
        }
      }
    }
  }
}


    curry(interval.start)要出现在偏移量>=2的位置,shooter(interval.end)要出现在偏移量<5的位置 并且curry和shooter之间的间距(intercal.gaps)为1 才可以查得到    

3) JavaSDK

* 参照下方DSL编写简单Java Api调用

虽然调用方式有所不同,不过最后本质上依然是一个queryBuilder工厂铸造的对象,可以放入bool中配合其他查询一起使用!
 

            {
              "query": {
                "intervals": {
                  "content": {
                    "all_of": {
                      "max_gaps": 5,
                      "ordered": true,
                      "intervals": [
                        {
                          "match": {
                            "query": "Curry shooter",
                            "max_gaps": 1,
                            "ordered": "true",
                            "filter": {
                              "not_containing": {
                                "match": {
                                  "query": "bad"
                                }
                              }
                            }
                          }
                        }
                      ]
                    },
                    "boost": 2
                  }
                }
              }
            }
 public void customerIntervalsQuery() throws IOException {
   
        // 构建intervals数组
        List<IntervalsSourceProvider> intervalsSourceProviderList = new ArrayList<>(16);
        // 构建内层match
        IntervalsSourceProvider.IntervalFilter intervalFilter = new IntervalsSourceProvider.IntervalFilter(new IntervalsSourceProvider.Match("bad", 0, true, null, null, null), "not_containing");
        IntervalsSourceProvider.Match mainProvider = new IntervalsSourceProvider.Match("Curry shooter", gaps, true, null, intervalFilter, null);
        // 将math加入intervals[]
        intervalsSourceProviderList.add(mainProvider);



        // 最后放入all of对象中
        IntervalsSourceProvider intervalsSourceProvider = new IntervalsSourceProvider.Combine(intervalsSourceProviderList, true, 5, null);
        // all of放入最外层的intervals
        IntervalQueryBuilder intervalQueryBuilder = new IntervalQueryBuilder("content", intervalsSourceProvider);
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(intervalQueryBuilder);
        System.out.println(searchSourceBuilder.toString());

		// 发送请求
        request.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        SearchHits hits = search.getHits();
        System.out.println(hits);
    }

Except for the passage of time and the separation of life and death,I can do all things.

参考资料:

Intervals query | Elasticsearch Guide [7.9] | Elastic

ElasticSearch官方文档

Elasticsearch Intervals query 间隔查询_yuanxun4683的博客-CSDN博客_elasticsearch interval

作者:墨菲灬

9.2.1-elasticsearch全文检索之intervals查询_红笺小字-CSDN博客

作者:hjx

elasticsearch 7.0 新特性之Intervals query - 简书

作者:码到成功_易企秀

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值