在 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.