我正在尝试使用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));
我想首先了解为什么带过滤器的查询对我不起作用。最后,我想实现一个查询,该查询搜索给定的关键字并根据找到该字段的字段(列,属性)对结果进行优先级排序。
因此,如果关键字位于“名称”字段中,则应在顶部将其返回。因此分别是“名称”,“编号”,“描述”。如何实现这样的查询?
编辑:我尝试下面的查询,但它不返回任何内容。
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))));
下面是一些样本数据;
当我将“2000”作为关键字发送时,我得到以下查询结果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
字段,而当您需要使用name.raw
查询/过滤器进行完全匹配时,就可以使用term
字段来查询。
关于c# - 嵌套具有字段优先级的查询和过滤查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32313755/