我尝试在elasticsearch中按主域查找子域名。 我添加了一些有弹性的域名:
$domains = [
'site.com',
'ns1.site.com',
'ns2.site.com',
'test.main.site.com',
'sitesite.com',
'test-site.com',
];
foreach ($domains as $domain) {
$params = [
'index' => 'my_index',
'type' => 'my_type',
'body' => ['domain' => $domain],
];
$client->index($params);
}
然后我尝试搜索:
$params = [
'index' => 'my_index',
'type' => 'my_type',
'body' => [
'query' => [
'wildcard' => [
'domain' => [
'value' => '.site.com',
],
],
],
],
];
$response = $client->search($params);
但是一无所获。 :(
我的映射是: https://pastebin.com/raw/k9MzjJUM
有任何想法要解决它吗?
由于
答案 0 :(得分:0)
你快到了,只缺少几件事。
在查询中添加*
就足够了(这就是为什么会调用此查询wildcard
):
POST my_index/my_type/_search
{
"query": {
"wildcard" : { "domain" : "*.site.com" }
}
}
这会给你以下结果:
{
...
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "my_index",
"_type": "my_type",
"_id": "RoE8VGMBRuo1XmkIXhp0",
"_score": 1,
"_source": {
"domain": "test.main.site.com"
}
}
]
}
}
似乎工作,但我们只得到一个结果(不是全部)。
返回您的映射,字段domain
的类型为text
:
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"domain": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
这意味着该字段的内容将被标记化并小写(使用standard分析器)。您可以使用_analyze
API查看哪些令牌可以实际搜索,如下所示:
POST _analyze
{
"text": "test.main.site.com"
}
{
"tokens": [
{
"token": "test.main.site.com",
"start_offset": 0,
"end_offset": 18,
"type": "<ALPHANUM>",
"position": 0
}
]
}
这就是wildcard
查询可以匹配test.main.site.com
的原因。
如果我们选择n1.site.com
怎么办?
POST _analyze
{
"text": "n1.site.com"
}
{
"tokens": [
{
"token": "n1",
"start_offset": 0,
"end_offset": 2,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "site.com",
"start_offset": 3,
"end_offset": 11,
"type": "<ALPHANUM>",
"position": 1
}
]
}
如您所见,没有以.site.com
结尾的令牌(请注意.
之前的site.com
)。
幸运的是,您的映射已经能够返回所有结果。
您可以使用keyword
字段,该字段使用确切的值进行查询:
POST my_index/my_type/_search
{
"query": {
"wildcard" : { "domain.keyword" : "*.site.com" }
}
}
这会给你以下结果:
{
"hits": {
"total": 3,
"max_score": 1,
"hits": [
{
"_index": "my_index",
"_type": "my_type",
"_id": "RoE8VGMBRuo1XmkIXhp0",
"_score": 1,
"_source": {
"domain": "test.main.site.com"
}
},
{
"_index": "my_index",
"_type": "my_type",
"_id": "Q4E8VGMBRuo1XmkIFRpy",
"_score": 1,
"_source": {
"domain": "ns1.site.com"
}
},
{
"_index": "my_index",
"_type": "my_type",
"_id": "RYE8VGMBRuo1XmkIORqG",
"_score": 1,
"_source": {
"domain": "ns2.site.com"
}
}
]
}
}
实际上,没有。 wildcard
次查询can be very slow:
请注意,此查询可能很慢,因为它需要迭代多次 条款。为了防止极慢的通配符查询,使用通配符 术语不应以其中一个通配符*或?开头。
为了获得最佳性能,在您的情况下,我建议您创建另一个字段higherLevelDomains
,并手动从原始字段中提取更高级别的域。该文件可能如下所示:
POST my_index/my_type
{
"domain": "test.main.site.com",
"higherLevelDomains": [
"main.site.com",
"site.com",
"com"
]
}
这将允许您使用term
查询:
POST my_index/my_type/_search
{
"query": {
"term" : { "higherLevelDomains.keyword" : "site.com" }
}
}
这可能是您可以使用Elasticsearch进行此类任务的最有效查询。
希望有所帮助!