我正在尝试使用空格进行搜索以在弹性搜索中正常工作,但在使其行为与在另一个字段上的行为方式相同时会遇到很多麻烦。
我有两个字段Name
和Addresses.First().Line1
,我希望能够在搜索中搜索和保留空格。例如,搜索Bob Smi*
会返回Bob Smith
,但不仅仅是Bob
。
这适用于我的“名称”字段,方法是使用?
替换空格进行查询字符串搜索。我也在做一个通配符,所以我的最终查询是*bob?smi*
。
然而,当我尝试也按行1搜索时,我没有得到任何结果。例如。 *4800*
会返回包含{1}}等第1行的记录,但当我使用4800 Street
进行相同的转换以获取4800 street
时,我得不到任何结果。
以下是我的查询
*4800?street*
不会返回任何结果。
为什么{
"from": 0,
"size": 50,
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "*4800?Street*",
"fields": [
"name",
"addresses.line1"
]
}
}
]
}
}
}
会返回名称为*bob?smi*
的结果,但Bob Smith
不会返回包含订单项*4800?street*
的结果?
以下是如何在索引中设置两个字段:
4800 street
弹性映射:
.Text(smd => smd.Name(c => c.Name).Analyzer(ElasticIndexCreator.SortAnalyzer).Fielddata())
.Nested<Address>(nomd => nomd.Name(p => p.PrimaryAddress).Properties(MapAddressProperties))
//from MapAddressProperties()
.Text(smd2 => smd2.Name(x => x.Line1).Analyzer(ElasticIndexCreator.SortAnalyzer).Fielddata())
还有其他更好的方法来逃避弹性搜索查询字符串中的空格吗?我还尝试了"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
"addresses": {
"line1": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
}
和\\
(在C#评估为\\\\
)而不是\\
无效。
答案 0 :(得分:0)
尝试在 中使用addresses.line1.keyword
参数keyword
(即,尝试为addresses.line1
定义的fields
多字段) term-level wildcard query:
{
"query": {
"wildcard": {
"addresses.line1.keyword": {
"wildcard": "*4800 street*"
}
}
}
}
按Elasticsearch documentation on full-text wildcard searches,如果您搜索addresses.line1
(其类型为text
,以便应用全文搜索规则),则会针对从字段中分析的每个字词执行搜索,即一次针对4800
再次针对street
,其中任何一个都不会与您的*4800?street*
通配符匹配。 addresses.line1.keyword
多字段包含原始4800 street
值,并且应使用术语级通配符查询与您的查询模式匹配。
顺便说一下,一个次要的:映射类型定义本身对addresses
字段来说似乎不完整。你说是:
"addresses": {
"line1": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
}
但恕我直言,它应该是:
"addresses": {
"properties": {
"line1": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
}
}
答案 1 :(得分:0)
经过大量时间的实验,终于找到了正确的设置。对我有用的配置如下:
?
,例如输入bob smith
,使用*bob?smith*
addresses.line1
会在搜索说4800
时返回数据,但在尝试*4800?street*
时则不会。使用嵌套查询可以使其正常运行。据我所知,不得不使用现场数据是非常耗费内存的,并且必须使用通配符是非常耗时的,所以这可能不是最佳解决方案,但它是我发现的唯一解决方案。如果还有另一种更好的方法,请赐教。
使用Nest在C#中进行查询:
var query = Query<Student>.QueryString(qs => qs
.Fields(f => f
.Field(c => c.Name)
//.Field(c => c.PrimaryAddress.Line1) //this doesn't work
)
.Query(testCase.Term)
);
query |= Query<Student>.Nested(n => n
.Path(p => p.Addresses)
.Query(q => q
.QueryString(qs => qs
.Fields(f => f.Field(c => c.Addresses.First().Line1))
.Query(testCase.Term)
)
)
);
示例映射:
.Map<Student>(s => s.Properties(p => p
.Text(t => t.Name(z => z.Name).Fielddata())
.Nested<StudentAddress>(n => n
.Name(ap => ap.Addresses)
.Properties(ap => ap.Text(t => t.Name(z => z.Line1).Fielddata())
)
))