Spring Data Elasticsearch 只返回完全匹配
Spring Data Elasticsearch only returning exact matches
我做了一个简单的项目来测试 free text search
使用 Spring Data Elasticsearch。这是我的实体:
@Document(indexName = "flag", type = "flag")
public class Flag {
@Id
private String flagCode;
@MultiField(mainField = @Field(type = FieldType.String))
private String flagName;
// setters and getters
}
现在,我的搜索操作如下所示:
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(fuzzyQuery("flagName", freeText))
.build();
List<Flag> flags = elasticsearchTemplate.queryForList(searchQuery, Flag.class);
有了这个,我只得到 flagName
与 flagName
完全匹配的对象,我希望如果至少有 2 个字符匹配,它应该是 匹配.
如果相关,我的 DataConfig
文件如下所示:
@Configuration
@EnableElasticsearchRepositories(basePackages = "com.shubham.dao")
@ComponentScan(basePackages = "com.shubham.data")
public class DataConfig {
@Value("${elasticsearch.clustername}")
private String clusterName;
@Value("${elasticsearch.host}")
private String elasticsearchHost;
@Value("${elasticsearch.port}")
private int elasticsearchPort;
@Bean
public Client client() throws Exception {
Settings esSettings = Settings.settingsBuilder()
.put("cluster.name", clusterName)
.build();
//https://www.elastic.co/guide/en/elasticsearch/guide/current/_transport_client_versus_node_client.html
return TransportClient.builder()
.settings(esSettings)
.build()
.addTransportAddress(
new InetSocketTransportAddress(InetAddress.getByName(elasticsearchHost), elasticsearchPort));
}
@Bean
public ElasticsearchOperations elasticsearchTemplate() throws Exception {
return new ElasticsearchTemplate(client());
}
}
我可能做错了什么?我是 Elasticsearch 的新手。
默认情况下,fuzzy
查询有一个 fuzziness setting of AUTO
,这意味着
- 如果字词的长度介于 0 到 2 个字符之间,则必须完全匹配。
- 如果字词长度在 3 到 5 个字符之间,则只允许进行一次编辑
- 在此之上,允许进行两次编辑
在您的情况下,当您索引 India
时,令牌 india
(小写)将被索引。
- 搜索
In
意味着 4 次编辑 => 没有匹配项
- 搜索
Ind
意味着 3 次编辑 => 没有匹配项
- 搜索
Indi
意味着 2 次编辑 => 没有匹配项
- 搜索
India
意味着 1 次编辑 => 匹配
您可能需要使用 edge-ngram 来标记您的数据,而不是使用完全不适合搜索前缀的模糊性,就像您似乎愿意做的那样。
我做了一个简单的项目来测试 free text search
使用 Spring Data Elasticsearch。这是我的实体:
@Document(indexName = "flag", type = "flag")
public class Flag {
@Id
private String flagCode;
@MultiField(mainField = @Field(type = FieldType.String))
private String flagName;
// setters and getters
}
现在,我的搜索操作如下所示:
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(fuzzyQuery("flagName", freeText))
.build();
List<Flag> flags = elasticsearchTemplate.queryForList(searchQuery, Flag.class);
有了这个,我只得到 flagName
与 flagName
完全匹配的对象,我希望如果至少有 2 个字符匹配,它应该是 匹配.
如果相关,我的 DataConfig
文件如下所示:
@Configuration
@EnableElasticsearchRepositories(basePackages = "com.shubham.dao")
@ComponentScan(basePackages = "com.shubham.data")
public class DataConfig {
@Value("${elasticsearch.clustername}")
private String clusterName;
@Value("${elasticsearch.host}")
private String elasticsearchHost;
@Value("${elasticsearch.port}")
private int elasticsearchPort;
@Bean
public Client client() throws Exception {
Settings esSettings = Settings.settingsBuilder()
.put("cluster.name", clusterName)
.build();
//https://www.elastic.co/guide/en/elasticsearch/guide/current/_transport_client_versus_node_client.html
return TransportClient.builder()
.settings(esSettings)
.build()
.addTransportAddress(
new InetSocketTransportAddress(InetAddress.getByName(elasticsearchHost), elasticsearchPort));
}
@Bean
public ElasticsearchOperations elasticsearchTemplate() throws Exception {
return new ElasticsearchTemplate(client());
}
}
我可能做错了什么?我是 Elasticsearch 的新手。
默认情况下,fuzzy
查询有一个 fuzziness setting of AUTO
,这意味着
- 如果字词的长度介于 0 到 2 个字符之间,则必须完全匹配。
- 如果字词长度在 3 到 5 个字符之间,则只允许进行一次编辑
- 在此之上,允许进行两次编辑
在您的情况下,当您索引 India
时,令牌 india
(小写)将被索引。
- 搜索
In
意味着 4 次编辑 => 没有匹配项 - 搜索
Ind
意味着 3 次编辑 => 没有匹配项 - 搜索
Indi
意味着 2 次编辑 => 没有匹配项 - 搜索
India
意味着 1 次编辑 => 匹配
您可能需要使用 edge-ngram 来标记您的数据,而不是使用完全不适合搜索前缀的模糊性,就像您似乎愿意做的那样。