跨多个弹性搜索类型进行查询



我想在弹性搜索 5.0 中获取以多种类型(类型 1 和 类型 2 和 类型 3...(存在的文档。我知道通过在 URL 中使用多种类型(如 type1,type2(以及过滤_type字段,可以跨多种类型进行搜索。但所有这些条件都是 OR(类型 1 或类型 2(。如何实现 AND 条件?

这是我的ES中的两个文档,

{
"_index":"cust_58e8700034fa4e368590fb1396e2641c",
"_type":"unique-fp-domains",
"_id":"n_d4dbba7309a94503b25eca735078f17c_258b3ad1a11aba282f35908662bdc5432d68fd96bf3ca90013dcdd5764331399",
"_version":2,
"_score":1,
"_source":{
"mg_timestamp":1579866709096,
"violated-directive":"connect-src",
"fp-hash":"258b3ad1a11aba282f35908662bdc5432d68fd96bf3ca90013dcdd5764331399",
"time":1579866709096,
"scan-id":"n_d4dbba7309a94503b25eca735078f17c",
"blocked-uri":"play.sundaysky.com"
}
}

{
"_index":"cust_58e8700034fa4e368590fb1396e2641c",
"_type":"tag-alexa-top1k-using-csp-tld-domain",
"_id":"AW_XY4P4kmprPQ28bTUb",
"_version":1,
"_score":1,
"_source":{
"tagged-domain":"sundaysky.com",
"tag-guidance":"FP",
"additional-tag-metadata-isbase64-encoded":"eyJ0b3RhbC1hbGV4YS1tYXRjaGVzIjoyMzh9",
"project-id":2,
"fp-hash":"258b3ad1a11aba282f35908662bdc5432d68fd96bf3ca90013dcdd5764331399",
"scan-id":"n_d4dbba7309a94503b25eca735078f17c",
}
}

我想从给定的 2 种类型的相同索引中获取文档"scan-id":"n_d4dbba7309a94503b25eca735078f17c"

我试过了,

{
"size": 100,
"query": {
"bool": {
"must": [
{
"bool": {
"filter": [
{
"term": {
"_type": {
"value": "tag-alexa-top1k-using-csp-tld-domain"
}
}
},
{
"term": {
"scan-id": {
"value": "n_d4dbba7309a94503b25eca735078f17c"
}
}
}
]
}
},
{
"bool": {
"filter": [
{
"term": {
"_type": {
"value": "unique-fp-domains"
}
}
},
{
"term": {
"scan-id": {
"value": "n_d4dbba7309a94503b25eca735078f17c"
}
}
}
]
}
}
]
}
}
}

但它不起作用。

Elasticsearch 在连接不同的文档集合方面并不擅长,但在您的情况下,您也许可以通过parent-child关系解决您的问题。

如何以 AND 方式一起查询多个索引类型?

如果您有一对多关系,您可以使用parent-child对其进行建模。假设类型unique-fp-domains是"父"类型,scan-id字段是唯一标识符。我们还假设tag-alexa-top1k-using-csp-tld-domain是一个"子文档",并且每个类型tag-alexa-top1k-using-csp-tld-domain的文档都恰好引用unique-fp-domains中的 1 个文档。

然后我们应该通过以下方式创建 Elasticsearch 映射:

PUT /cust_58
{
"mappings": {
"unique-fp-domains": {},
"tag-alexa-top1k-using-csp-tld-domain": {
"_parent": {
"type": "unique-fp-domains" 
}
}
}
}

并像这样插入文档:

# "parent"
PUT /cust_58/unique-fp-domains/n_d4dbba7309a94503b25eca735078f17c
{
"mg_timestamp": 1579866709096,
"violated-directive": "connect-src",
"fp-hash": "258b3ad1a11aba282f35908662bdc5432d68fd96bf3ca90013dcdd5764331399",
"time": 1579866709096,
"scan-id": "n_d4dbba7309a94503b25eca735078f17c",
"blocked-uri": "play.sundaysky.com"
}
# "child"
POST /cust_58/tag-alexa-top1k-using-csp-tld-domain?parent=n_d4dbba7309a94503b25eca735078f17c
{
"tagged-domain": "sundaysky.com",
"tag-guidance": "FP",
"additional-tag-metadata-isbase64-encoded": "eyJ0b3RhbC1hbGV4YS1tYXRjaGVzIjoyMzh9",
"project-id": 2,
"fp-hash": "258b3ad1a11aba282f35908662bdc5432d68fd96bf3ca90013dcdd5764331399",
"scan-id": "n_d4dbba7309a94503b25eca735078f17c"
}

现在,我们将能够查询具有任何与之关联的子对象的父对象 == 在父 ID 上加入,这是我们通过手动提供文档_id来强制scan-id的。

查询将使用has_child,如下所示:

POST /cust_58/unique-fp-domains/_search
{
"query": {
"has_child": {
"type": "tag-alexa-top1k-using-csp-tld-domain",
"query": {
"match_all": {}
},
"inner_hits": {}
}
}
}

请注意,我们使用inner_hits来告诉 Elasticsearch 检索匹配的"子"文档。

输出如下所示:

"hits": [
{
"_index": "cust_58",
"_type": "unique-fp-domains",
"_id": "n_d4dbba7309a94503b25eca735078f17c",
"_score": 1.0,
"_source": {
"mg_timestamp": 1579866709096,
"violated-directive": "connect-src",
...
},
"inner_hits": {
"tag-alexa-top1k-using-csp-tld-domain": {
"hits": {
"total": 1,
"max_score": 1.0,
"hits": [
{
"_type": "tag-alexa-top1k-using-csp-tld-domain",
"_id": "AW_xhfnnIzWDkoWd1czA",
"_score": 1.0,
"_routing": "n_d4dbba7309a94503b25eca735078f17c",
"_parent": "n_d4dbba7309a94503b25eca735078f17c",
"_source": {
"tagged-domain": "sundaysky.com",
...
}

使用parent-child有什么缺点?

  • 父 ID 应该是唯一的
  • 仅通过家长 ID 加入
  • 一些性能开销:

    如果您关心查询性能,则不应使用此查询。

  • 要启用父子项,必须更改映射并重新索引现有数据

需要考虑的其他重要事项

在 Elasticsearch 6 中,类型已被删除。好消息是,从Elasticsearch 5开始,人们可以使用join数据类型。

一般来说,Elasticsearch 不太擅长管理对象之间的关系,但处理它们的方法很少。

希望对您有所帮助!

我认为这个查询会找出你的问题;

"query": {
"bool": {
"must": [
{
"terms": {
"_type": "tag-alexa-top1k-using-csp-tld-domain"
}
},
{
"terms": {
"_type": "unique-fp-domains"
}
}
],
"filter": [
{
"scan-id": {
"_type": "n_d4dbba7309a94503b25eca735078f17c"
}
}
]
}
}

"query": { "query_string" : { "query" : "(_type : unique-fp-domains OR tag-alexa-top1k-using-csp-tld-domain( AND (scan-id : n_d4dbba7309a94503b25eca735078f17c(
} }

你可以使用msearch。这可以组合多个搜索。您可以在他们的文档中找到有关此内容的更多信息。https://www.elastic.co/guide/en/elasticsearch/reference/current/search-multi-search.html

最新更新