具有 ID 列表的 Elasticsearch 多匹配过滤器
Elasticsearch multimatch filtered with list of Ids
我是 ES 的新手,我正在尝试解决以下问题。
我使用以下配置在我的 Elasticsearch 中创建了一个索引:
client.Indices.Create(lineItemIndex,
c => c
.Settings(s => s
.Setting("max_ngram_diff", 13)
.Analysis(a => a
.Tokenizers(tf => tf
.NGram("mynGram", td => td
.MaxGram(15).MinGram(2)))
.Analyzers(aa => aa
.Custom("mynGram_analyzer", ca => ca
.Filters(new List<string> {"lowercase"})
.Tokenizer("mynGram")))))
.Map<ElasticSearchLineItem>(m => m
.Properties(ps => ps
.Text(ss => ss
.Name(na => na.LineItemName)
.Fields(ff => ff
.Keyword(k => k
.Name("keyword"))
.Text(tx => tx
.Name("fulltext")
.Analyzer("whitespace")
.Boost(10.0))
.Text(tx => tx
.Name("partial")
.Analyzer("mynGram_analyzer")
.Boost(1.0)))))
.Properties(ps => ps
.Keyword(kw => kw
.Name(na => na.LineItemId)
.Index(false)))
.Properties(ps => ps
.Keyword(kw => kw
.Name(na => na.Id)
.Index(false)))
.Properties(ps => ps
.Text(ss => ss
.Name(na => na.LineItemNumber)
.Fields(ff => ff
.Keyword(k => k
.Name("keyword"))
.Text(tx => tx
.Name("fulltext")
.Analyzer("whitespace")
.Boost(10.0))
.Text(tx => tx
.Name("partial")
.Analyzer("mynGram_analyzer")
.Boost(1.0)))))
.Properties(ps => ps
.Keyword(ss => ss
.Name(na => na.SupplierName)
.Index(false)))
.Properties(ps => ps
.Keyword(ss => ss
.Name(na => na.Unit)
.Index(false)))
.Properties(ps => ps
.Number(ss => ss
.Name(na => na.PriceAmount)
.Type(NumberType.ScaledFloat).ScalingFactor(100)
.Index(false)))
.Properties(ps => ps
.Keyword(ss => ss
.Name(na => na.Currency)
.Index(false)))
.Properties(ps => ps
.Keyword(ss => ss
.Name(na => na.SupplierId)
.Index(false)))
.Properties(ps => ps
.Text(ss => ss
.Name(na => na.ImageUrl)
.Index(false)))
.Properties(ps => ps
.Text(ss => ss
.Name(na => na.SupplierPriceListId)
.Index(false)))));
在我的解决方案中,我们有一个用于搜索的搜索框。
但是,我们还假设能够根据 SupplierId
过滤搜索。因此,进行搜索的人可能有多个 SupplierId
他们只想查看来自
的结果
我尝试创建以下查询:
var esSearch2 = new SearchDescriptor<ElasticSearchLineItem>()
.From(0)
.Take(250)
.Query(q => q
.Bool(b => b
.Must(mu => mu
.MultiMatch(m => m
.Fields(f => f
.Field(ff => ff
.LineItemName.Suffix("fulltext"))
.Field(ff => ff
.LineItemName.Suffix("partial"))
.Field(ff => ff
.LineItemNumber.Suffix("fulltext"))
.Field(ff => ff
.LineItemNumber.Suffix("partial")))
.Query(request.SearchWord)
.Fuzziness(Fuzziness.Auto)
))
.Filter(f => f
.Terms(t => t
.Verbatim()
.Field(p => p
.SupplierId.Suffix("keyword"))
.Terms(request.ListOfFavorites.ToArray())))));
无论 request.ListOfFavorites
是否为空,这个 return 都没有。但是如果我删除我的过滤器,它会正确 return 结果。
我想我遗漏了一些东西,或者我的订单搞砸了。有人可以帮忙吗?
注意:我使用的是 ES 7.5.1 和 NEST 7.5.1
编辑:
我更改了我的索引,并从我的 supplierId 字段中删除了 Index(false)
。
这是更新后kibana中显示的映射
{
"mapping": {
"properties": {
"currency": {
"type": "keyword",
"index": false
},
"id": {
"type": "keyword",
"index": false
},
"imageUrl": {
"type": "text",
"index": false
},
"lineItemId": {
"type": "keyword",
"index": false
},
"lineItemName": {
"type": "text",
"fields": {
"fulltext": {
"type": "text",
"boost": 10,
"analyzer": "whitespace"
},
"keyword": {
"type": "keyword"
},
"partial": {
"type": "text",
"analyzer": "mynGram_analyzer"
}
}
},
"lineItemNumber": {
"type": "text",
"fields": {
"fulltext": {
"type": "text",
"boost": 10,
"analyzer": "whitespace"
},
"keyword": {
"type": "keyword"
},
"partial": {
"type": "text",
"analyzer": "mynGram_analyzer"
}
}
},
"priceAmount": {
"type": "scaled_float",
"index": false,
"scaling_factor": 100
},
"supplierId": {
"type": "keyword"
},
"supplierName": {
"type": "keyword",
"index": false
},
"supplierPriceListId": {
"type": "text",
"index": false
},
"unit": {
"type": "keyword",
"index": false
}
}
}
}
在您的映射中,您将 SupplierId
指定为 excluded from the index,因此您将无法对其进行搜索。
.Properties(ps => ps
.Keyword(ss => ss
.Name(na => na.SupplierId)
.Index(false)))
另外,您不需要为您的字段指定后缀,因为它没有定义为多字段,所以只需
.Filter(f => f
.Terms(t => t
.Verbatim()
.Field(p => p.SupplierId)
.Terms(request.ListOfFavorites.ToArray())))));
够了。
希望对您有所帮助。
我是 ES 的新手,我正在尝试解决以下问题。
我使用以下配置在我的 Elasticsearch 中创建了一个索引:
client.Indices.Create(lineItemIndex,
c => c
.Settings(s => s
.Setting("max_ngram_diff", 13)
.Analysis(a => a
.Tokenizers(tf => tf
.NGram("mynGram", td => td
.MaxGram(15).MinGram(2)))
.Analyzers(aa => aa
.Custom("mynGram_analyzer", ca => ca
.Filters(new List<string> {"lowercase"})
.Tokenizer("mynGram")))))
.Map<ElasticSearchLineItem>(m => m
.Properties(ps => ps
.Text(ss => ss
.Name(na => na.LineItemName)
.Fields(ff => ff
.Keyword(k => k
.Name("keyword"))
.Text(tx => tx
.Name("fulltext")
.Analyzer("whitespace")
.Boost(10.0))
.Text(tx => tx
.Name("partial")
.Analyzer("mynGram_analyzer")
.Boost(1.0)))))
.Properties(ps => ps
.Keyword(kw => kw
.Name(na => na.LineItemId)
.Index(false)))
.Properties(ps => ps
.Keyword(kw => kw
.Name(na => na.Id)
.Index(false)))
.Properties(ps => ps
.Text(ss => ss
.Name(na => na.LineItemNumber)
.Fields(ff => ff
.Keyword(k => k
.Name("keyword"))
.Text(tx => tx
.Name("fulltext")
.Analyzer("whitespace")
.Boost(10.0))
.Text(tx => tx
.Name("partial")
.Analyzer("mynGram_analyzer")
.Boost(1.0)))))
.Properties(ps => ps
.Keyword(ss => ss
.Name(na => na.SupplierName)
.Index(false)))
.Properties(ps => ps
.Keyword(ss => ss
.Name(na => na.Unit)
.Index(false)))
.Properties(ps => ps
.Number(ss => ss
.Name(na => na.PriceAmount)
.Type(NumberType.ScaledFloat).ScalingFactor(100)
.Index(false)))
.Properties(ps => ps
.Keyword(ss => ss
.Name(na => na.Currency)
.Index(false)))
.Properties(ps => ps
.Keyword(ss => ss
.Name(na => na.SupplierId)
.Index(false)))
.Properties(ps => ps
.Text(ss => ss
.Name(na => na.ImageUrl)
.Index(false)))
.Properties(ps => ps
.Text(ss => ss
.Name(na => na.SupplierPriceListId)
.Index(false)))));
在我的解决方案中,我们有一个用于搜索的搜索框。
但是,我们还假设能够根据 SupplierId
过滤搜索。因此,进行搜索的人可能有多个 SupplierId
他们只想查看来自
我尝试创建以下查询:
var esSearch2 = new SearchDescriptor<ElasticSearchLineItem>()
.From(0)
.Take(250)
.Query(q => q
.Bool(b => b
.Must(mu => mu
.MultiMatch(m => m
.Fields(f => f
.Field(ff => ff
.LineItemName.Suffix("fulltext"))
.Field(ff => ff
.LineItemName.Suffix("partial"))
.Field(ff => ff
.LineItemNumber.Suffix("fulltext"))
.Field(ff => ff
.LineItemNumber.Suffix("partial")))
.Query(request.SearchWord)
.Fuzziness(Fuzziness.Auto)
))
.Filter(f => f
.Terms(t => t
.Verbatim()
.Field(p => p
.SupplierId.Suffix("keyword"))
.Terms(request.ListOfFavorites.ToArray())))));
无论 request.ListOfFavorites
是否为空,这个 return 都没有。但是如果我删除我的过滤器,它会正确 return 结果。
我想我遗漏了一些东西,或者我的订单搞砸了。有人可以帮忙吗?
注意:我使用的是 ES 7.5.1 和 NEST 7.5.1
编辑:
我更改了我的索引,并从我的 supplierId 字段中删除了 Index(false)
。
这是更新后kibana中显示的映射
{
"mapping": {
"properties": {
"currency": {
"type": "keyword",
"index": false
},
"id": {
"type": "keyword",
"index": false
},
"imageUrl": {
"type": "text",
"index": false
},
"lineItemId": {
"type": "keyword",
"index": false
},
"lineItemName": {
"type": "text",
"fields": {
"fulltext": {
"type": "text",
"boost": 10,
"analyzer": "whitespace"
},
"keyword": {
"type": "keyword"
},
"partial": {
"type": "text",
"analyzer": "mynGram_analyzer"
}
}
},
"lineItemNumber": {
"type": "text",
"fields": {
"fulltext": {
"type": "text",
"boost": 10,
"analyzer": "whitespace"
},
"keyword": {
"type": "keyword"
},
"partial": {
"type": "text",
"analyzer": "mynGram_analyzer"
}
}
},
"priceAmount": {
"type": "scaled_float",
"index": false,
"scaling_factor": 100
},
"supplierId": {
"type": "keyword"
},
"supplierName": {
"type": "keyword",
"index": false
},
"supplierPriceListId": {
"type": "text",
"index": false
},
"unit": {
"type": "keyword",
"index": false
}
}
}
}
在您的映射中,您将 SupplierId
指定为 excluded from the index,因此您将无法对其进行搜索。
.Properties(ps => ps
.Keyword(ss => ss
.Name(na => na.SupplierId)
.Index(false)))
另外,您不需要为您的字段指定后缀,因为它没有定义为多字段,所以只需
.Filter(f => f
.Terms(t => t
.Verbatim()
.Field(p => p.SupplierId)
.Terms(request.ListOfFavorites.ToArray())))));
够了。
希望对您有所帮助。