温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么使用Elasticsearch中的Span Query

发布时间:2021-11-17 13:50:51 来源:亿速云 阅读:903 作者:iii 栏目:大数据

本篇内容介绍了“怎么使用Elasticsearch中的Span Query”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

Span查询是低级的位置查询,提供对指定术语的顺序和邻近性的专家控制。它们通常用于实现对法律文件或专利的非常具体的查询。

Span query 指的是es的区间查询,通过该语句用户可以精准控制多个输入词的先后顺序,以及多个关键词在文档中的前后距离

注意:不能将Span查询与非Span查询混合使用(span_multi查询除外)。

数据准备阶段

POST index_name/_analyze
{
  "field": "name",   
  "text": "边建军"
}

结果:
{
  "tokens" : [
    {
      "token" : "边",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<IDEOGRAPHIC>",
      "position" : 0
    },
    {
      "token" : "建",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "<IDEOGRAPHIC>",
      "position" : 1
    },
    {
      "token" : "军",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "<IDEOGRAPHIC>",
      "position" : 2
    }
  ]
}

备注:
name字段的分词为Es的默认标准分词

Span Term Query

与普通的term检索类似,用来获取某个字段包含特定term的文档。

{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "span_term": {
            "name": {
              "value": "杜建新",
              "boost": 2
            }
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  }
}

boolQueryBuilder.must(QueryBuilders.spanTermQuery("name", q).boost(2));

Span Multi Term Query

{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "span_multi": {
            "match": {
              "prefix": {
                "name": {
                  "value": "杜建新",
                  "boost": 1
                }
              }
            },
            "boost": 1
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  }
}

PrefixQueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery("name", q);
boolQueryBuilder.must(QueryBuilders.spanMultiTermQueryBuilder(prefixQueryBuilder));
或者
MultiTermQueryBuilder multiTermQueryBuilder = QueryBuilders.prefixQuery("name", q);
boolQueryBuilder.must(QueryBuilders.spanMultiTermQueryBuilder(multiTermQueryBuilder));

备注:
可以是扩展MultiTermQueryBuilder类的任何构建器。
例如:FuzzyQueryBuilder, PrefixQueryBuilder, RangeQueryBuilder, RegexpQueryBuilder或WildcardQueryBuilder。

如果与查询匹配的术语数量超过了布尔查询限制(默认为1024),span_multi查询将遇到太多子句失败。为了避免无限制的扩展,可以将多术语查询的rewrite方法设置为top_terms_* rewrite。或者,如果您仅在前缀查询上使用span_multi,则可以激活文本字段的index_prefixes字段选项。这会将字段上的任何前缀查询重写为与索引前缀匹配的单个词查询。

Span First Query

从文档开始位置至end结束位置进行关键词查找,当end设置为1时,那么关键词必须匹配在文档开头。

{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "span_first": {
            "match": {
              "span_term": {
                "name": {
                  "value": "杜建新",
                  "boost": 1
                }
              }
            },
            "end": 2,
            "boost": 1
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  }
}

SpanQueryBuilder spanQueryBuilder = QueryBuilders.spanTermQuery("name", q);
boolQueryBuilder.must(QueryBuilders.spanFirstQuery(spanQueryBuilder, 4));

Span near query

span near可以用来对多个关键词进行顺序查找。

模板:
spanNearQuery(spanTermQuery("field","value1"), 12)                                                  
     .addClause(spanTermQuery("field","value2"))      
     .addClause(spanTermQuery("field","value3"))      
     .inOrder(false); 

案例:
{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "span_near": {
            "clauses": [
              {
                "span_term": {
                  "name": {
                    "value": "边",
                    "boost": 1
                  }
                }
              },
              {
                "span_term": {
                  "name": {
                    "value": "军",
                    "boost": 1
                  }
                }
              }
            ],
            "slop": 1,
            "in_order": true,
            "boost": 1
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  }
}

SpanQueryBuilder spanQueryBuilder_1 = QueryBuilders.spanTermQuery("name", q);
SpanQueryBuilder spanQueryBuilder_2 = QueryBuilders.spanTermQuery("name", q);

boolQueryBuilder.must(QueryBuilders.spanNearQuery(spanQueryBuilder_1, 2)
       .addClause(spanQueryBuilder_2).inOrder(true));


备注:有结果返回
如果slop改为0时,将不会有数据返回

其中in_order需要设置为true,且后一个关键词的start_offset减去前一个end_offset的值必须小于等于slop

Span Or Query

可以指定多个查询子句,每种查询返回的数据进行合并处理

模板:
spanOrQuery(spanTermQuery("field","value1"))                 
    .addClause(spanTermQuery("field","value2"))              
    .addClause(spanTermQuery("field","value3")); 

案例:
{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "span_or": {
            "clauses": [
              {
                "span_term": {
                  "name": {
                    "value": "边",
                    "boost": 1
                  }
                }
              },
              {
                "span_term": {
                  "name": {
                    "value": "军",
                    "boost": 1
                  }
                }
              }
            ],
            "boost": 1
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  }
}

SpanQueryBuilder spanQueryBuilder_1 = QueryBuilders.spanTermQuery("name", q);
SpanQueryBuilder spanQueryBuilder_2 = QueryBuilders.spanTermQuery("name", q);
boolQueryBuilder.must(QueryBuilders.spanOrQuery(spanQueryBuilder_1)
       .addClause(spanQueryBuilder_2));


备注:相当于match query里的should语句
查询子句可以更换为任意的span query

Span Not Query

模板:
spanNotQuery(
        spanTermQuery("field","value1"),                     
        spanTermQuery("field","value2"));  

案例:
{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "span_not": {
            "include": {
              "span_term": {
                "name": {
                  "value": "杜",
                  "boost": 1
                }
              }
            },
            "exclude": {
              "span_term": {
                "name": {
                  "value": "新",
                  "boost": 1
                }
              }
            },
            "pre": 0,
            "post": 0,
            "boost": 1
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  }
}

SpanQueryBuilder spanQueryBuilder_1 = QueryBuilders.spanTermQuery("name", q);
SpanQueryBuilder spanQueryBuilder_2 = QueryBuilders.spanTermQuery("name", q);
boolQueryBuilder.must(QueryBuilders.spanNotQuery(spanQueryBuilder_1, spanQueryBuilder_2));

备注:相当于match query中的must not
include用于定义包含的span查询;exclude用于定义排除的span查询

Span Containing Query

span containing与span within用法相同,只是底层调用的Lucene方法不同而已,效果是一样的。

这个查询内部会有多个子查询,但是会设定某个子查询优先级更高,作用更大,通过关键字little和big来指定。

模板:
spanContainingQuery(
        spanNearQuery(spanTermQuery("field1","bar"), 5)      
            .addClause(spanTermQuery("field1","baz"))
            .inOrder(true),
        spanTermQuery("field1","foo"));       

案例:
{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "span_containing": {
            "big": {
              "span_term": {
                "name": {
                  "value": "杜",
                  "boost": 1
                }
              }
            },
            "little": {
              "span_term": {
                "name": {
                  "value": "新",
                  "boost": 1
                }
              }
            },
            "boost": 1
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  }
}

SpanQueryBuilder spanQueryBuilder_1 = QueryBuilders.spanTermQuery("name", q);
SpanQueryBuilder spanQueryBuilder_2 = QueryBuilders.spanTermQuery("name", q);
boolQueryBuilder.must(QueryBuilders.spanContainingQuery(spanQueryBuilder_1, spanQueryBuilder_2));

Span Within Query

模板:
spanWithinQuery(
        spanNearQuery(spanTermQuery("field1", "bar"), 5)     
            .addClause(spanTermQuery("field1", "baz"))
            .inOrder(true),
        spanTermQuery("field1", "foo"));

“怎么使用Elasticsearch中的Span Query”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI