我正在尝试使用Nest使用ElasticSearch构建搜索功能。我需要的是:
我有产品表,我索引如下:
foreach (var product in products) {
Product product = new Product(product.ProductId, product.Name, product.Number, product.Description);
ElasticClient.Index(productes);
}
然后我执行以下查询:
这很好用。我得到了结果。
var results = ElasticClient.Search<Product>(body => body.Query(query => query.QueryString(qs => qs.Query(key))).Size(20));
以下查询都不起作用。为什么?我做错了什么?
-
var results = ElasticClient.Search<Product>(body => body.Filter(filter => filter.Term(x => x.Name, key)).Take(1000));
-
var results = ElasticClient.Search<Product>(s => s
.From(0)
.Size(15)
.Query(q => q
.Term(p => p.Name, key)));
-
var results = ElasticClient.Search<Product>(body => body.Query(query => query.ConstantScore(csq => csq.Filter(filter => filter.Term(x => x.Name, key.ToLower())))).Take(1000));
我想首先理解为什么带过滤器的查询对我不起作用。最后,我想实现一个搜索给定关键字的查询,并根据找到的字段(列,属性)对结果进行优先级排序。
因此,如果关键字位于&#34;名称&#34;字段,它应该返回顶部。分别是&#34;姓名&#34;,&#34;号码&#34;,&#34;说明&#34;。我怎样才能实现这样的查询?
编辑:我尝试了下面的查询,但它没有返回任何内容。
var results = ElasticClient.Search<Product>(body => body
.Query(q => q
.QueryString(qs => qs
.OnFieldsWithBoost(d => d
.Add(entry => entry.Name, 5.0)
.Add(entry => entry.Number, 3.0)
.Add(entry => entry.Description, 2.0))
.Query(key))));
以下一些样本数据; 当我发送&#34; 2000&#34;作为关键字,我得到以下结果1.查询但其他人不会返回任何内容。
答案 0 :(得分:1)
第一个查询返回结果而其他查询不返回结果的主要原因是第一个查询是query_string
,输入关键字(例如2000
)将被分析并与之匹配你的领域(也进行了分析)。这不是第二次,第三次和第四次查询的情况,因为您使用的是term
查询/过滤器,其中未分析输入,而是将匹配为。
如果我们获取第一个文档(id = 13),则name
字段将被分析并编入索引为以下标记:dr
,2000
,12k
(用小写!)可以用以下命令看到:
curl -XGET 'localhost:9200/_analyze?pretty&analyzer=standard' -d 'DR-2000 (12k)'
{
"tokens" : [ {
"token" : "dr",
"start_offset" : 0,
"end_offset" : 2,
"type" : "<ALPHANUM>",
"position" : 1
}, {
"token" : "2000",
"start_offset" : 3,
"end_offset" : 7,
"type" : "<NUM>",
"position" : 2
}, {
"token" : "12k",
"start_offset" : 9,
"end_offset" : 12,
"type" : "<ALPHANUM>",
"position" : 3
} ]
}
因此,在2000
查询中搜索dr
(或12k
或query_string
)时,您会找到该文档。搜索术语2000
不会产生任何结果,这在使用term
查询/过滤器进行精确匹配时是预期的。
至于关于提升字段的第二个问题,查询返回任何内容的原因可能是因为字段名称are lowercased by default(NEST的默认行为)。您应该确保使用小写字段名称。
<强>更新强>
如果您需要执行完全匹配,我建议您使用analyzed
和not_analyzed
字段将字段映射更改为multi-field string fields。
{
"product" : {
"properties" : {
"name" : {
"type" : "string",
"index" : "analyzed",
"fields" : {
"raw" : {"type" : "string", "index" : "not_analyzed"}
}
}
}
}
}
然后,当您需要喜欢行为时,可以使用name
查询query_string
字段;当您需要与{{1完全匹配的行为时,name.raw
字段查询/过滤。