我正在开发建筑资料库查询。
这是我要编写的查询。
在我的存储库中,我有一个如下所示的文档:
我一直在比赛:
以下是一些无效的尝试:
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"term": {
"address1": {
"value": "45 myrtle street"
}
}
},
{
"term": {
"siteName": {
"value": "myrtle"
}
}
}
]
}
},
{
"term": {
"zipCode": {
"value": "90210"
}
}
}
]
}
}
}
{
"query": {
"filtered": {
"query": {
"term": {
"zipCode": {
"value": "90210"
}
}
},
"filter": {
"or": {
"filters": [
{
"term": {
"address1": "45 myrtle street"
}
},
{
"term": {
"siteName": "myrtle"
}
}
]
}
}
}
}
}
{
"filter": {
"bool": {
"must": [
{
"or": {
"filters": [
{
"term": {
"address1": "45 myrtle street"
}
},
{
"term": {
"siteName": "myrtle"
}
}
]
}
},
{
"term": {
"zipCode": "90210"
}
}
]
}
}
}
{
"query": {
"bool": {
"must": [
{
"span_or": {
"clauses": [
{
"span_term": {
"siteName": {
"value": "myrtle"
}
}
}
]
}
},
{
"term": {
"zipCode": {
"value": "90210"
}
}
}
]
}
}
}
{
"query": {
"filtered": {
"query": {
"term": {
"zipCode": {
"value": "90210"
}
}
},
"filter": {
"or": {
"filters": [
{
"term": {
"address1": "45 myrtle street"
}
},
{
"term": {
"siteName": "myrtle"
}
}
]
}
}
}
}
}
有人知道我在做什么错吗?
我正在用NEST编写此代码,因此我更喜欢NEST语法,但是ElasticSearch语法当然也足够。
编辑:根据@Greg Marzouka的评论,以下是映射:
{
[indexname]: {
"mappings": {
"[indexname]elasticsearchresponse": {
"properties": {
"address": {
"type": "string"
},
"address1": {
"type": "string"
},
"address2": {
"type": "string"
},
"address3": {
"type": "string"
},
"city": {
"type": "string"
},
"country": {
"type": "string"
},
"id": {
"type": "string"
},
"originalSourceId": {
"type": "string"
},
"placeId": {
"type": "string"
},
"siteName": {
"type": "string"
},
"siteType": {
"type": "string"
},
"state": {
"type": "string"
},
"systemId": {
"type": "long"
},
"zipCode": {
"type": "string"
}
}
}
}
}
}
最佳答案
根据您的映射,您将无法在siteName
上搜索精确匹配项,因为它是使用standard analyzer进行分析的,而ojit_a更适合于全文搜索。当没有在字段上明确定义时,这是Elasticsearch所应用的默认分析器。
标准分析器将siteName
的值分成多个 token 。例如,Myrtle Street
被标记并作为两个单独的术语存储在索引中,即myrtle
和street
,这就是查询与该文档匹配的原因。对于不区分大小写的精确匹配,您希望将Myrtle Street
作为单个小写的 token 存储在索引中:myrtle street
。
您可以将siteName
设置为not_analyzed
,这完全不会使该字段服从分析链,这意味着不会修改值。但是,这将产生一个Myrtle Street
token ,该 token 可用于完全匹配,但区分大小写。
您需要做的是使用关键字标记器和小写标记过滤器创建一个自定义分析器,然后将其应用于您的字段。
使用NEST的流利API的方法如下:
// Create the custom analyzer using the keyword tokenizer and lowercase token filter
var myAnalyzer = new CustomAnalyzer
{
Tokenizer = "keyword",
Filter = new [] { "lowercase" }
};
var response = this.Client.CreateIndex("your-index-name", c => c
// Add the customer analyzer to your index settings
.Analysis(an => an
.Analyzers(az => az
.Add("my_analyzer", myAnalyzer)
)
)
// Create the mapping for your type and apply "my_analyzer" to the siteName field
.AddMapping<YourType>(m => m
.MapFromAttributes()
.Properties(ps => ps
.String(s => s.Name(t => t.SiteName).Analyzer("my_analyzer"))
)
)
);