是否有任何解决方案可以做到" NOT IN" Elasticsearch中的功能?

时间:2015-01-07 10:42:30

标签: mysql elasticsearch lucene aggregation logstash

这是一个简单但困难的问题。 我想对查询结果进行聚合,该结果应该使用" 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" }'

我真正想要的是"其user_id未根据这些日志数据注册的文档"。 所以,文件[ 4,5,9,10 ]是我想要的最终结果。

是否有可能在Elasticsearch中获得我想要的结果?

提前致谢。

2 个答案:

答案 0 :(得分:0)

不,elasticsearch不会进行连接,而您要求的是连接的变体。

如上所述,它确实有父子关系和嵌套对象,虽然这可能对你有所帮助,具体取决于你的域。

Elasticsearch也没有您需要的独特功能。但你可以用术语聚合来伪装它。

然而,这对你没有帮助,因为你真的需要一个联接。所以,这里唯一的解决方案是在elasticsearch之外进行连接。根据您的数据大小,这可能会很昂贵。另请参阅application side joins

答案 1 :(得分:-1)

如果您使用not filter Elasticsearch将依次检查每个文档 - 以下将返回所有文档,其中actionsignup之外的任何内容}。

curl -XGET http://localhost:9200/myindex/my_type/_search?pretty -d '{
  "query": {
    "filtered": {
        "filter": {
           "not" : {
            "term" : { "action" : "signup" }
           }
        }
     }
  }
}'

要满足返回用户标识的要求,如果它没有action=signup的任何实例,那么您需要设置parent child relationship

在这种情况下,Userid在所有user类型文档中都是唯一的。每个用户文档都有一个或多个action类型的子项。

以下查询检查action子项并返回user文档。

curl -XGET 'http://localhost:9200/myindex/my_type/_search?pretty' -d '{
 "query": {
   "filtered": {
    "filter": {
      "not" : {
       "has_child": { "type": "my_action", "term" : { "action" : "signup" }}
      }
    }
   }  
 }
}'