【全文搜索引擎】Elasticsearch之模糊查询

wildcard查询

通配符查询允许我们在查询值中使用*和?等通配符。此外,通配符查询跟词条查询在内容方面非常类似。可以发送一下查询,来匹配所有包含cr?me词条的文档,这里?表示任意字符:

{
	"query" : {
		"wildcard" : {
			"title" : "cr?me"
		}
	}
}

这将匹配title字段中包含与cr?me匹配的词条的所有文档。然后,还可以在通配符查询中包含加权属性;它将影响每个与给定值匹配的词条的重要性。如果要改变之前的查询,给它一个20.0的加权,可以发出以下查询:

{
	"query" : {
		"wildcard" : {
			"title" : {
				"value" : "cr?me",
				"boost" : 20.0
			}
		}
	}
}

注意,通配符查询不太注重性能,在可能时应尽量避免,特别是要避免前缀通配符(以通配符开始的词条)。此外,请注意Elasticsearch会重写通配符查询,因此Elasticsearch允许通过一个额外的参数控制重写方法。

代码实现:
GET goods/_search
{
	"query" : {
		"wildcard" : {
			"brandName" : {
				"value" : "华*",
			}
		}
	}
}
java代码
/**
 * 模糊查询:WildcardQuery
 */
@Test
public void testWildcardQuery() throws IOException {
	// 构建查询请求对象,指定查询的索引名称
    SearchRequest searchRequest = new SearchRequest("goods");
	// 创建查询条件构建器SearchSourceBuilder
    SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
    // 查询条件
    WildcardQueryBuilder query = QueryBuilders.wildcardQuery("title", "华*");
    // 指定查询条件
    sourceBulider.query(query);
    // 添加查询条件构建器 SearchSourceBuilder
    searchRequest.source(sourceBulider);
	// 查询,获取查询结果
    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
	// 获取命中对象 SearchHits
    SearchHits searchHits = searchResponse.getHits();
    //获取记录数
    long value = searchHits.getTotalHits().value;
    System.out.println("总记录数:"+value);

    List<Goods> goodsList = new ArrayList<>();
    // 获取Hits数据  数组
    SearchHit[] hits = searchHits.getHits();
    for (SearchHit hit : hits) {
    	// 获取json字符串格式的数据
        String sourceAsString = hit.getSourceAsString();
        //转为java
        Goods goods = JSON.parseObject(sourceAsString, Goods.class);
        goodsList.add(goods);
    }

    for (Goods goods : goodsList) {
        System.out.println(goods);
    }
}

regexp查询

通过正则表达式查询,可以使用正则表达式来查询文本。请记住,此类查询的性能取决于所选的正则表达式。如果我们的正则表达式匹配许多词条,查询将很慢。一般规则是,正则表达式匹配的词条数越高,查询越慢。
正则表达式查询示例如下所示:

{
	"query" : {
		"regexp" : {
			"title" : {
				"value" : "cr.m[ae]",
				"boost" : 10.0
			}
		}
	}
}

上述查询将被Elasticsearch重写成若干个词条查询,根据索引中匹配给定正则表达式的内容。查询中加权参数指定了生成的查询将使用的加权值。

代码实现:
GET goods/_search
{
	"query" : {
		"regexp" : {
			"title" : {
				"value" : "\\w+(.)*",
			}
		}
	}
}
java代码
/**
 * 模糊查询:regexpQuery
 */
@Test
public void testRegexpQuery() throws IOException {
	// 构建查询请求对象,指定查询的索引名称
    SearchRequest searchRequest = new SearchRequest("goods");
	// 创建查询条件构建器SearchSourceBuilder
    SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
    // 查询条件
    RegexpQueryBuilder query = QueryBuilders.regexpQuery("title", "\\w+(.)*");
    // 指定查询条件
    sourceBulider.query(query);
    // 添加查询条件构建器 SearchSourceBuilder
    searchRequest.source(sourceBulider);
	// 查询,获取查询结果
    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
	// 获取命中对象 SearchHits
    SearchHits searchHits = searchResponse.getHits();
    //获取记录数
    long value = searchHits.getTotalHits().value;
    System.out.println("总记录数:"+value);

    List<Goods> goodsList = new ArrayList<>();
    // 获取Hits数据  数组
    SearchHit[] hits = searchHits.getHits();
    for (SearchHit hit : hits) {
    	// 获取json字符串格式的数据
        String sourceAsString = hit.getSourceAsString();
        // 转为java
        Goods goods = JSON.parseObject(sourceAsString, Goods.class);
        goodsList.add(goods);
    }

    for (Goods goods : goodsList) {
        System.out.println(goods);
    }
}

prefix查询

前缀查询在配置方面来说跟词条查询类似。前缀查询能让我们匹配这样的文档:它们的特定字段以给定的前缀开始。例如,想找到所有title字段以cri开始的文档,可以运行以下查询:

{
	"query" : {
		"prefix" : {
			"title" : "cri"
		}
	}
}

与词条查询类似,还可以在前缀查询中包含加权属性;这将影响到给定前缀的重要性。例如,改变之前的查询,并给它增加3.0的加权,发出以下查询:

{
	"query" : {
		"prefix" : {
			"title" : {
				"value" : "cri",
				"boost" : 3.0
			}
		}
	}
}

Elasticsearch会把前缀查询重写,也允许我们传递额外的参数来控制重写方法。

代码实现:
GET goods/_search
{
	"query" : {
		"prefix" : {
			"title" : {
				"value" : "华",
			}
		}
	}
}
java代码
/**
 * 模糊查询:perfixQuery
 */
@Test
public void testPrefixQuery() throws IOException {
	// 构建查询请求对象,指定查询的索引名称
    SearchRequest searchRequest = new SearchRequest("goods");
	// 创建查询条件构建器SearchSourceBuilder
    SearchSourceBuilder sourceBulider = new SearchSourceBuilder();
    // 查询条件
    PrefixQueryBuilder query = QueryBuilders.prefixQuery("brandName", "三");
    // 指定查询条件
    sourceBulider.query(query);
    // 添加查询条件构建器 SearchSourceBuilder
    searchRequest.source(sourceBulider);
	// 查询,获取查询结果
    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
	// 获取命中对象 SearchHits
    SearchHits searchHits = searchResponse.getHits();
    //获取记录数
    long value = searchHits.getTotalHits().value;
    System.out.println("总记录数:"+value);

    List<Goods> goodsList = new ArrayList<>();
    // 获取Hits数据  数组
    SearchHit[] hits = searchHits.getHits();
    for (SearchHit hit : hits) {
    	//获取json字符串格式的数据
        String sourceAsString = hit.getSourceAsString();
        //转为java
        Goods goods = JSON.parseObject(sourceAsString, Goods.class);
        goodsList.add(goods);
    }

    for (Goods goods : goodsList) {
        System.out.println(goods);
    }
}
发布了34 篇原创文章 · 获赞 14 · 访问量 1568

猜你喜欢

转载自blog.csdn.net/Wan_Yuan/article/details/105508668