elasticsearch 多条件搜索语句怎么写

发布网友 发布时间:2022-04-19 09:57

我来回答

5个回答

懂视网 时间:2022-05-06 17:39

首先我们来看看为什么存在这些问题,以及如何解决它们。

问题1:在多个字段中匹配相同的单词

考虑一下most_fields查询是如何执行的:ES会为每个字段生成一个match查询,让后将它们包含在一个bool查询中。

我们可以将查询传入到validate-query API中进行查看:

GET /_validate/query?explain
{
 "query": {
 "multi_match": {
 "query": "Poland Street W1V",
 "type": "most_fields",
 "fields": [ "street", "city", "country", "postcode" ]
 }
 }
}

它会产生下面的解释(explaination):

(street:poland street:street street:w1v) (city:poland city:street city:w1v) (country:poland country:street country:w1v) (postcode:poland postcode:street postcode:w1v)

你可以发现能够在两个字段中匹配poland的文档会比在一个字段中匹配了poland和street的文档的分值要高。

问题2:减少长尾

在精度控制(Controlling Precision)一节中,我们讨论了如何使用and操作符和minimum_should_match参数来减少相关度低的文档数量:

{
 "query": {
 "multi_match": {
  "query": "Poland Street W1V",
  "type": "most_fields",
  "operator": "and", 
  "fields": [ "street", "city", "country", "postcode" ]
 }
 }
}

但是,使用best_fields或者most_fields,这些参数会被传递到生成的match查询中。该查询的解释如下(译注:通过validate-query API):

(+street:poland +street:street +street:w1v) (+city:poland +city:street +city:w1v) (+country:poland +country:street +country:w1v) (+postcode:poland +postcode:street +postcode:w1v)

换言之,使用and操作符时,所有的单词都需要出现在相同的字段中,这显然是错的!这样做可能不会有任何匹配的文档。

问题3:词条频度

在什么是相关度(What is Relevance)一节中,我们解释了默认用来计算每个词条的相关度分值的相似度算法TF/IDF:

词条频度(Term Frequency)

在一份文档中,一个词条在一个字段中出现的越频繁,文档的相关度就越高。

倒排文档频度(Inverse Document Frequency)

一个词条在索引的所有文档的字段中出现的越频繁,词条的相关度就越低。

当通过多字段进行搜索时,TF/IDF会产生一些令人惊讶的结果。

考虑使用first_name和last_name字段搜索"Peter Smith"的例子。Peter是一个常见的名字,Smith是一个常见的姓氏 - 它们的IDF都较低。但是如果在索引中有另外一个名为Smith Williams的人呢?Smith作为名字是非常罕见的,因此它的IDF值会很高!

像下面这样的一个简单查询会将Smith Williams放在Peter Smith前面(译注:含有Smith Williams的文档分值比含有Peter Smith的文档分值高),尽管Peter Smith明显是更好的匹配:

{
 "query": {
 "multi_match": {
  "query": "Peter Smith",
  "type": "most_fields",
  "fields": [ "*_name" ]
 }
 }
}

smith在first_name字段中的高IDF值会压倒peter在first_name字段和smith在last_name字段中的两个低IDF值。

解决方案

这个问题仅在我们处理多字段时存在。如果我们将所有这些字段合并到一个字段中,该问题就不复存在了。我们可以向person文档中添加一个full_name字段来实现:

{
 "first_name": "Peter",
 "last_name": "Smith",
 "full_name": "Peter Smith"
}

当我们只查询full_name字段时:

  • 拥有更多匹配单词的文档会胜过那些重复出现一个单词的文档。
  • minimum_should_match和operator参数能够正常工作。
  • first_name和last_name的倒排文档频度会被合并,因此smith无论是first_name还是last_name都不再重要。

    尽管这种方法能工作,可是我们并不想存储冗余数据。因此,ES为我们提供了两个解决方案 - 一个在索引期间,一个在搜索期间。下一节对它们进行讨论。

    热心网友 时间:2022-05-06 14:47

    Elasticsearch是一个高伸缩、高可用、基于ApacheLucene的开源搜索与分析引擎。通过它你可以很方便地对数据进行深入挖掘,可以随时放大与缩小搜索与分析的区间,并且这一切都是实时的。为了提供了一个优秀的用户体验,我们对Elasticsearch投入了很大的精力。Elasticsearch本身的各种选项已有了良好的默认值,使用户能够更方便地上手。但我们也为用户提供了全方面的选项,在必要的情况下,可以对该引擎的几乎每个方面进行定制。举例来说,当你使用它搜索数据的时候,可以使用传统的查询(‘查找满足条件Y的所有项X’)进行过滤(在Elasticsearch术语中称为逗视图地),高亮显示搜索片段,为每条结果提供相应的上下文。也可以使用地理位置(‘查找在Z里之内的所有项’),或是为用户提供搜索关键字建议,并且提供了强大的聚合(即Elasticsearch中的逗分面地(facet))能力,例如时间分布图或者统计图。Elasticsearch既可以搜索、也可以保存数据。它提供了一种半结构化、不依赖schema并且基于JSON的模型,你可以直接传入原始的JSON文档,Elasticsearch会自动地检测出你的数据类型,并对文档进行索引。你也可以对schema映射进行定制,以实现你的目的,例如对单独的字段或文档进行boost映射,或者是定制全文搜索的分析方式等等。你既可以在自己的膝上电脑中启用一个小型实例,也可以在云端启用几十乃至几百个实例,只需要一些极小的改变而已。Elasticsearch会自动进行横向扩展,它能够随着你的应用一起成长。Elasticsearch运行在JVM之上,它使用JSON格式,通过RESTfulHTTP接口的方式访问,因此任何一种客户端或语言都能够与其交互。目前已经有了大量的客户端和框架的整合方案,包括对多种编程语言的支持,通过这些原生的API与专门的DSL将不一致的地方最小化,并实现性能最大化。Elasticsearch非常适合于大数据的场合,它的高伸缩性与分布式架构的本质使得对大量信息的搜索与存储都可以在近乎实时的情况下完成。通过Elasticsearch-Hadoop这个项目,我们使Hadoop使用者(这里也包括Hive、Pig和Cascading)能够用一个成熟的搜索引擎来增强他们的工作流。我们还为他们提供了一种丰富的语言,能够让他们更好地表达意图,因而更准确地获得想要的结果,并且速度也大大提高了。追问RESTful API 的json
    怎么写这个语句呢

    热心网友 时间:2022-05-06 16:05

    以下代码是动态构建查询语句:

    [java] view plain copy private SearchRequestBuilder dynamicSearch(String index, String type, String startTime, String endTime, String status, String title, String city, String resOfficer, int pageIndex, int pageCapacity) { SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index) .setTypes(type) .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) .setPostFilter(FilterBuilders.rangeFilter("start_time").from(startTime).to(endTime)) .setFrom(pageIndex).setSize(pageCapacity) .setExplain(true); BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); queryBuilder.mustNot(QueryBuilders.matchQuery("site", "www.huodongxing.com")); //活动名称 if (!StringUtils.isEmpty(title)) { queryBuilder.must(QueryBuilders.queryString(title).field("title")); } //城市 if (!StringUtils.isEmpty(city)) { queryBuilder.must(termQuery("city", city)); } //业务状态 if (!StringUtils.isEmpty(status)) { if (status.equals(BusinessStatus.REJECTED.getCode()) || status.equals(BusinessStatus.COOPERATED.getCode())) { queryBuilder.must(termQuery("bus_status", status)); } } //负责人 if (!StringUtils.isEmpty(resOfficer)) { queryBuilder.must(queryString(resOfficer).field("resOfficer")); } if (StringUtils.isEmpty(title) && StringUtils.isEmpty(city) && StringUtils.isEmpty(status) && StringUtils.isEmpty(resOfficer)) { searchRequestBuilder.setQuery(matchAllQuery()); } searchRequestBuilder.setQuery(queryBuilder); return searchRequestBuilder; }追问请问你懂
    基于JSON 的RESTful API写法吗 我没有学过java

    热心网友 时间:2022-05-06 17:40

    {
    "query": {
    "bool": {
    "filter": {
    "bool": {
    "must": [{
    "term": {
    "name": "john"
    }
    },
    {
    "term": {
    "sex": "男"
    }
    },
    {
    "rang": {
    "age": {
    "gt": 10,
    "lt": 30
    }
    }
    }
    ]
    }
    }
    }
    }
    }

    热心网友 时间:2022-05-06 19:31

    。。。我看下面的回答。。。现在会写了吗?

  • 声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
    16.155787s