在 Elasticsearch 中执行 "NOT IN" 功能有什么解决方案吗?
Is there any solution to do the "NOT IN" functionality in Elasticsearch?
这是一个简单但困难的问题。
我想对应该使用 "NOT IN" 功能的查询结果进行聚合,就像任何 RDBMS 的 SQL.
例如,我想做如下的工作。
curl -XGET http://localhost:9200/my_index/my_type/_search?pretty -d '{
"query": {
"filtered": {
"filter": {
!!! Documents whose 'user_id' field value is 'NOT IN' distinct user_ids where the 'action' field value is 'signup' !!!
}
}
},
"aggregations": {
"distinct_users":{
"cardinality": {
"field": "user_id",
"precision_threshold": 1000000
}
}
}
}'
编辑
这是一个示例数据。
curl -s -XPOST 'localhost:9200/my_index/my_type/1' -d'{ "user_id": 1234, "action": "signup" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/2' -d'{ "user_id": 1234, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/3' -d'{ "user_id": 1234, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/4' -d'{ "user_id": 5678, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/5' -d'{ "user_id": 5678, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/6' -d'{ "user_id": 9012, "action": "signup" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/7' -d'{ "user_id": 9012, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/8' -d'{ "user_id": 9012, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/9' -d'{ "user_id": 3456, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/10' -d'{ "user_id": 3456, "action": "visit" }'
我真正想要得到的是"Documents whose user_id DOES NOT signed up based on these log data"。
所以,文档 [4, 5, 9, 10] 就是我想要得到的最终结果。
Elasticsearch是否可以得到我想要的结果?
提前致谢。
如果您使用 not filter Elasticsearch 将依次检查每个文档 - 以下将 return 所有 个具有操作的文档 action
不是 signup
.
curl -XGET http://localhost:9200/myindex/my_type/_search?pretty -d '{
"query": {
"filtered": {
"filter": {
"not" : {
"term" : { "action" : "signup" }
}
}
}
}
}'
如果用户 ID 没有 action=signup
的任何实例,则要满足 returned 用户 ID 的要求,则您需要设置 parent child relationship。
在这种情况下,Userid 在所有 user
类型的文档中都是唯一的。每个用户文档都有一个或多个 action
类型的子文档。
以下查询检查 action
子文档和 return 文档 user
。
curl -XGET 'http://localhost:9200/myindex/my_type/_search?pretty' -d '{
"query": {
"filtered": {
"filter": {
"not" : {
"has_child": { "type": "my_action", "term" : { "action" : "signup" }}
}
}
}
}
}'
不,elasticsearch 不进行连接,您要求的是连接的变体。
如上所述,它确实具有父子关系和嵌套对象,不过这可能对您有所帮助,具体取决于您的域。
Elasticsearch 也没有您需要的独特功能。但是您可以使用术语聚合来伪造它。
但是,这对您没有帮助,因为您确实需要加入。因此,这里唯一的解决方案是在 elasticsearch 之外进行连接。根据您的数据大小,这可能很昂贵。另见 application side joins.
这是一个简单但困难的问题。 我想对应该使用 "NOT IN" 功能的查询结果进行聚合,就像任何 RDBMS 的 SQL.
例如,我想做如下的工作。
curl -XGET http://localhost:9200/my_index/my_type/_search?pretty -d '{
"query": {
"filtered": {
"filter": {
!!! Documents whose 'user_id' field value is 'NOT IN' distinct user_ids where the 'action' field value is 'signup' !!!
}
}
},
"aggregations": {
"distinct_users":{
"cardinality": {
"field": "user_id",
"precision_threshold": 1000000
}
}
}
}'
编辑
这是一个示例数据。
curl -s -XPOST 'localhost:9200/my_index/my_type/1' -d'{ "user_id": 1234, "action": "signup" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/2' -d'{ "user_id": 1234, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/3' -d'{ "user_id": 1234, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/4' -d'{ "user_id": 5678, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/5' -d'{ "user_id": 5678, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/6' -d'{ "user_id": 9012, "action": "signup" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/7' -d'{ "user_id": 9012, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/8' -d'{ "user_id": 9012, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/9' -d'{ "user_id": 3456, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/10' -d'{ "user_id": 3456, "action": "visit" }'
我真正想要得到的是"Documents whose user_id DOES NOT signed up based on these log data"。 所以,文档 [4, 5, 9, 10] 就是我想要得到的最终结果。
Elasticsearch是否可以得到我想要的结果?
提前致谢。
如果您使用 not filter Elasticsearch 将依次检查每个文档 - 以下将 return 所有 个具有操作的文档 action
不是 signup
.
curl -XGET http://localhost:9200/myindex/my_type/_search?pretty -d '{
"query": {
"filtered": {
"filter": {
"not" : {
"term" : { "action" : "signup" }
}
}
}
}
}'
如果用户 ID 没有 action=signup
的任何实例,则要满足 returned 用户 ID 的要求,则您需要设置 parent child relationship。
在这种情况下,Userid 在所有 user
类型的文档中都是唯一的。每个用户文档都有一个或多个 action
类型的子文档。
以下查询检查 action
子文档和 return 文档 user
。
curl -XGET 'http://localhost:9200/myindex/my_type/_search?pretty' -d '{
"query": {
"filtered": {
"filter": {
"not" : {
"has_child": { "type": "my_action", "term" : { "action" : "signup" }}
}
}
}
}
}'
不,elasticsearch 不进行连接,您要求的是连接的变体。
如上所述,它确实具有父子关系和嵌套对象,不过这可能对您有所帮助,具体取决于您的域。
Elasticsearch 也没有您需要的独特功能。但是您可以使用术语聚合来伪造它。
但是,这对您没有帮助,因为您确实需要加入。因此,这里唯一的解决方案是在 elasticsearch 之外进行连接。根据您的数据大小,这可能很昂贵。另见 application side joins.