ElasticSearch 匹配 int 和 string 列表
ElasticSearch match on list of int and string
我是 ElasticSearch 的新手,我正在尝试查询我们的类别页面,其中 ES 返回的每个产品都在该类别中。出于某种原因,它包括该类别之外的产品,我似乎无法弄清楚为什么。
产品是基本产品,包含类别id列表(产品可以在多个类别中)。除了在categoryId上匹配外,它还应该在产品名称和变体的详细描述中搜索。
public IReadOnlyCollection<Product> GetByCategory(string value, int take, int categoryId)
{
value = string.Format("*{0}*", value);
var query = new SearchDescriptor<Product>()
.Index(this.index)
.Query(q => q
.Bool(b => b
.Must(s => s
.Match(m => m
.Field(ff => ff
.AttachedCategoryIds.Contains(categoryId)
)
)
)
.Must(s => s
.QueryString(m => m
.Query(value)
.Fields(ff => ff
.Field(f => f.Name)
.Field(f => f.Variants.Select(input => input.LongDescription))
)
.Type(TextQueryType.CrossFields)
)
)
)
)
.Size(take)
.Sort(ss => ss.Descending(SortSpecialField.Score));
var data = client.Search<Product>(query);
var products = data.Documents;
return products;
}
我希望从 elastic 返回当前类别的产品,但出于某种原因,它给了我不在 category/in 不同类别中的产品。
您的查询不正确。假设以下 POCO
public class Product
{
public string Name { get; set; }
public List<Variant> Variants { get; set; }
public List<int> AttachedCategoryIds { get; set; }
}
public class Variant
{
public string LongDescription { get; set; }
}
查询类似于
var index = "index_name";
var categoryId = 1;
var value = "this is the query";
var take = 20;
var query = new SearchDescriptor<Product>()
.Index(index)
.Query(q => q
.Bool(b => b
.Must(s => s
.QueryString(m => m
.Query(value)
.Fields(ff => ff
.Field(f => f.Name)
.Field(f => f.Variants.First().LongDescription)
)
.Type(TextQueryType.CrossFields)
)
)
.Filter(f => f
.Term(ff => ff.AttachedCategoryIds, categoryId)
)
)
)
.Size(take)
.Sort(ss => ss.Descending(SortSpecialField.Score));
var searchResponse = client.Search<Product>(query);
一些积分
.Field(f => f.Variants.First().LongDescription)
是一个 表达式 ,它将解析为将在 JSON 中序列化以定位 Elasticsearch 中的字段的字符串.在这种情况下,这将解析为 "variants.longDescription"
A term
query 可用于确定 Elasticsearch 中的字段是否包含特定值。我已将查询放入 bool
查询过滤器子句中,因为我认为您不想计算这部分查询的相关性分数,即文档在字段中包含术语或没有.
这将序列化为以下查询
POST http://localhost:9200/index_name/product/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"attachedCategoryIds": {
"value": 1
}
}
}
],
"must": [
{
"query_string": {
"fields": [
"name",
"variants.longDescription"
],
"query": "this is the query",
"type": "cross_fields"
}
}
]
}
},
"size": 20,
"sort": [
{
"_score": {
"order": "desc"
}
}
]
}
此查询假设 Product
上的 Variants
映射为 object
数据类型。它可以更 succinctly written 为
var query = new SearchDescriptor<Product>()
.Index(index)
.Query(q => q
.QueryString(m => m
.Query(value)
.Fields(ff => ff
.Field(f => f.Name)
.Field(f => f.Variants.First().LongDescription)
)
.Type(TextQueryType.CrossFields)
) && +q
.Term(ff => ff.AttachedCategoryIds, categoryId)
)
.Size(take)
.Sort(ss => ss.Descending(SortSpecialField.Score));
我是 ElasticSearch 的新手,我正在尝试查询我们的类别页面,其中 ES 返回的每个产品都在该类别中。出于某种原因,它包括该类别之外的产品,我似乎无法弄清楚为什么。
产品是基本产品,包含类别id列表(产品可以在多个类别中)。除了在categoryId上匹配外,它还应该在产品名称和变体的详细描述中搜索。
public IReadOnlyCollection<Product> GetByCategory(string value, int take, int categoryId)
{
value = string.Format("*{0}*", value);
var query = new SearchDescriptor<Product>()
.Index(this.index)
.Query(q => q
.Bool(b => b
.Must(s => s
.Match(m => m
.Field(ff => ff
.AttachedCategoryIds.Contains(categoryId)
)
)
)
.Must(s => s
.QueryString(m => m
.Query(value)
.Fields(ff => ff
.Field(f => f.Name)
.Field(f => f.Variants.Select(input => input.LongDescription))
)
.Type(TextQueryType.CrossFields)
)
)
)
)
.Size(take)
.Sort(ss => ss.Descending(SortSpecialField.Score));
var data = client.Search<Product>(query);
var products = data.Documents;
return products;
}
我希望从 elastic 返回当前类别的产品,但出于某种原因,它给了我不在 category/in 不同类别中的产品。
您的查询不正确。假设以下 POCO
public class Product
{
public string Name { get; set; }
public List<Variant> Variants { get; set; }
public List<int> AttachedCategoryIds { get; set; }
}
public class Variant
{
public string LongDescription { get; set; }
}
查询类似于
var index = "index_name";
var categoryId = 1;
var value = "this is the query";
var take = 20;
var query = new SearchDescriptor<Product>()
.Index(index)
.Query(q => q
.Bool(b => b
.Must(s => s
.QueryString(m => m
.Query(value)
.Fields(ff => ff
.Field(f => f.Name)
.Field(f => f.Variants.First().LongDescription)
)
.Type(TextQueryType.CrossFields)
)
)
.Filter(f => f
.Term(ff => ff.AttachedCategoryIds, categoryId)
)
)
)
.Size(take)
.Sort(ss => ss.Descending(SortSpecialField.Score));
var searchResponse = client.Search<Product>(query);
一些积分
.Field(f => f.Variants.First().LongDescription)
是一个 表达式 ,它将解析为将在 JSON 中序列化以定位 Elasticsearch 中的字段的字符串.在这种情况下,这将解析为"variants.longDescription"
A
term
query 可用于确定 Elasticsearch 中的字段是否包含特定值。我已将查询放入bool
查询过滤器子句中,因为我认为您不想计算这部分查询的相关性分数,即文档在字段中包含术语或没有.
这将序列化为以下查询
POST http://localhost:9200/index_name/product/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"attachedCategoryIds": {
"value": 1
}
}
}
],
"must": [
{
"query_string": {
"fields": [
"name",
"variants.longDescription"
],
"query": "this is the query",
"type": "cross_fields"
}
}
]
}
},
"size": 20,
"sort": [
{
"_score": {
"order": "desc"
}
}
]
}
此查询假设 Product
上的 Variants
映射为 object
数据类型。它可以更 succinctly written 为
var query = new SearchDescriptor<Product>()
.Index(index)
.Query(q => q
.QueryString(m => m
.Query(value)
.Fields(ff => ff
.Field(f => f.Name)
.Field(f => f.Variants.First().LongDescription)
)
.Type(TextQueryType.CrossFields)
) && +q
.Term(ff => ff.AttachedCategoryIds, categoryId)
)
.Size(take)
.Sort(ss => ss.Descending(SortSpecialField.Score));