簡體   English   中英

在elasticsearch中對postgresql的分區進行排名

[英]Rank over partition from postgresql in elasticsearch

我們面臨着將大型數據集遷移到postgres(備份或其他)的彈性搜索中的問題。

我們有類似這樣的架構

+---------------+--------------+------------+-----------+
|    user_id    |  created_at  |  latitude  | longitude |
+---------------+--------------+------------+-----------+
|       5       |  23.1.2015   |    12.49   |    20.39  |
+---------------+--------------+------------+-----------+
|       2       |  23.1.2015   |    12.42   |    20.32  |
+---------------+--------------+------------+-----------+
|       2       |  24.1.2015   |    12.41   |    20.31  |
+---------------+--------------+------------+-----------+
|       5       |  25.1.2015   |    12.45   |    20.32  |
+---------------+--------------+------------+-----------+
|       1       |  23.1.2015   |    12.43   |    20.34  |
+---------------+--------------+------------+-----------+
|       1       |  24.1.2015   |    12.42   |    20.31  |
+---------------+--------------+------------+-----------+

由於SQL中的rank函數,我們可以通過created_at找到最新的位置

... WITH locations AS ( 
select user_id, lat, lon, rank() over (partition by user_id order by created_at) as r
FROM locations)
SELECT user_id, lat, lon FROM locations WHERE r = 1

結果只為每個用戶創建了最新的位置:

+---------------+--------------+------------+-----------+
|    user_id    |  created_at  |  latitude  | longitude |
+---------------+--------------+------------+-----------+
|       2       |  24.1.2015   |    12.41   |    20.31  |
+---------------+--------------+------------+-----------+
|       5       |  25.1.2015   |    12.45   |    20.32  |
+---------------+--------------+------------+-----------+
|       1       |  24.1.2015   |    12.42   |    20.31  |
+---------------+--------------+------------+-----------+

將數據導入elasticsearch后,我們的文檔模型如下所示:

{
   "location" : { "lat" : 12.45, "lon" : 46.84 },
   "user_id"  : 5,
   "created_at" : "2015-01-24T07:55:20.606+00:00"
}
etc...

我正在尋找彈性搜索查詢中這個SQL查詢的替代方案,我認為它必須是可能的,但我還沒有找到。

你可以使用inner_hits使用inner_hits field collapsing inner_hits來實現這inner_hits

{
    "collapse": {
        "field": "user_id",
        "inner_hits": {
            "name": "order by created_at",
            "size": 1,
            "sort": [
                {
                    "created_at": "desc"
                }
            ]
        }
    },
}

詳細文章: https//blog.francium.tech/sql-window-function-partition-by-in-elasticsearch-c2e3941495b6

這很簡單:如果你想找到最舊的記錄(對於給定的id),你只需要沒有舊的 (具有相同id)的記錄。 (這假設對於給定的id,不存在具有相同 created_at日期的記錄)


SELECT * FROM locations ll
WHERE NOT EXISTS (
   SELECT * FROM locations nx
   WHERE nx.user_id = ll.user_id
   AND nx.created_at > ll.created_at
   );

編輯(似乎OP想要最新的觀察,而不是最古老的觀察)

使用top_hits。

    "aggs": {
    "user_id": {
    "terms": {"field": "user_id"},
    "aggs": {
        "top_location": {
          "top_hits": {
            "size": 1,
            "sort": { "created_at": "asc" },
            "_source": []
          }
        }
    }
 }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM