具有字段优先级和过滤器查询的嵌套查询
Nest queries with field priority and filter query
我正在尝试使用 Nest 通过 ElasticSearch 构建搜索功能。我需要的是:
我有产品 table,我的索引如下:
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));
以下两个 none 查询都有效。为什么?我做错了什么?
-
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));
我想首先了解为什么带过滤器的查询对我不起作用。最后,我想实现一个查询,该查询搜索给定的关键字并根据找到的字段(列,属性)对结果进行优先排序。
因此,如果关键字位于 "name" 字段中,则应将其 return 放在顶部。所以分别是"Name"、"Number"、"Description"。我怎样才能实现这样的查询?
编辑:我尝试了下面的查询,但它没有 return 任何东西。
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. 查询但其他人不会 return 任何东西。
第一个查询 returns 结果而其他查询没有结果的主要原因是因为第一个查询是 query_string
而输入关键字(例如 2000
)将是分析并匹配您的任何字段(也被分析)。这不是第二个、第三个和第四个查询的情况,因为您使用的是 term
query/filter,其中输入未被分析,而是按原样匹配 .
如果我们获取第一个文档 (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
} ]
}
因此,当在 query_string
查询中搜索 2000
(或 dr
或 12k
)时,您会找到该文档。搜索术语 2000
不会产生任何结果,这在使用适用于精确匹配的 term
query/filter 时是预期的。
关于你关于提升字段的第二个问题,查询 returns nothing 的原因可能是因为字段名称 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"}
}
}
}
}
}
然后你可以在需要 like 行为时用 query_string
查询 name
字段,在需要精确匹配时用 name.raw
字段查询term
query/filter.
的行为
我正在尝试使用 Nest 通过 ElasticSearch 构建搜索功能。我需要的是:
我有产品 table,我的索引如下:
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));
以下两个 none 查询都有效。为什么?我做错了什么?
-
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));
我想首先了解为什么带过滤器的查询对我不起作用。最后,我想实现一个查询,该查询搜索给定的关键字并根据找到的字段(列,属性)对结果进行优先排序。
因此,如果关键字位于 "name" 字段中,则应将其 return 放在顶部。所以分别是"Name"、"Number"、"Description"。我怎样才能实现这样的查询?
编辑:我尝试了下面的查询,但它没有 return 任何东西。
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. 查询但其他人不会 return 任何东西。
第一个查询 returns 结果而其他查询没有结果的主要原因是因为第一个查询是 query_string
而输入关键字(例如 2000
)将是分析并匹配您的任何字段(也被分析)。这不是第二个、第三个和第四个查询的情况,因为您使用的是 term
query/filter,其中输入未被分析,而是按原样匹配 .
如果我们获取第一个文档 (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
} ]
}
因此,当在 query_string
查询中搜索 2000
(或 dr
或 12k
)时,您会找到该文档。搜索术语 2000
不会产生任何结果,这在使用适用于精确匹配的 term
query/filter 时是预期的。
关于你关于提升字段的第二个问题,查询 returns nothing 的原因可能是因为字段名称 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"}
}
}
}
}
}
然后你可以在需要 like 行为时用 query_string
查询 name
字段,在需要精确匹配时用 name.raw
字段查询term
query/filter.