#filter #powerquery
#Фильтр #PowerQuery
Вопрос:
В настоящее время я получаю много данных из моей базы данных CosmosDB, которые я хочу сократить до последних 8 недель.
Как я могу фильтровать в PowerQuery, чтобы получить последние 8 недель на основе моего столбца даты.
Это мой powerquery для получения данных:
let
Source = DocumentDB.Contents("https://xxx.xxx", "xxx", "xxx"),
#"Expanded Document" = Table.ExpandRecordColumn(Source, "Document", {"$v"}, {"Document.$v"}),
#"Expanded Document.$v" = Table.ExpandRecordColumn(#"Expanded Document", "Document.$v", {"date"}, {"Document.$v.date"}),
#"Expanded Document.$v.date" = Table.ExpandRecordColumn(#"Expanded Document.$v", "Document.$v.date", {"$v"}, {"Document.$v.date.$v"}),
#"Changed Type" = Table.TransformColumnTypes(#"Expanded Document.$v.date",{{"Document.$v.date.$v", type text}})
in
#"Changed Type"
И вот как данные находятся в моей базе данных CosmosDB:
{
"_id" : ObjectId("5c6144bdf7ce070001acc213"),
"date" : {
"$date" : 1549792055030
},
Ответ №1:
Если вы хотите выполнить всю работу со своей стороны (возможно, сервер может выполнить некоторые / все это):
- Предполагая
1549792055030
, что (показано в примере) — это временная метка Unix, выраженная в миллисекундах, для преобразования вdatetime
запрос in Power попробуйте что-то вроде:#datetime(1970, 1, 1, 0, 0, 0) #duration(0, 0, 0, 1549792055030/1000)
- Кажется, вы расширяете поле записи с именем
$v
(которое само было вложено в поле с именемdate
, которое само было вложено в поле с именем$v
) в вашемM
коде, но$v
не отображается как присутствующее в структуре. Я упоминаю об этом, поскольку непонятно, следовать ли вашемуM
коду или структуре. Я собираюсь предположить, что у вас есть$v
поле, которое содержитdate
поле, которое само содержит$date
поле. Чтобы получить вложенную временную метку Unix, вы можете попробовать что-то вроде:someRecord[#"$v"][date][#"$date"]
- Поскольку вас интересуют только последние 8 недель, вы можете протестировать что-то вроде:
Date.IsInPreviousNWeeks(DateTime.AddZone(someDatetime, 0), 8)
. (Вы также можете сделать это другим способом, преобразовав8 weeks ago before now
в временную метку Unix, а затем отфильтровав временные метки>=
по полученному вами значению.)
Собрав все вышесказанное вместе, мы могли бы получить некоторый M
код, который выглядит следующим образом:
let
Source = DocumentDB.Contents("https://xxx.xxx", "xxx", "xxx"),
filterDates = Table.SelectRows(Source, each
let
millisecondsSinceEpoch = Number.From([document][#"$v"][date][#"$date"]),
toDatetime = #datetime(1970, 1, 1, 0, 0, 0) #duration(0, 0, 0, millisecondsSinceEpoch/1000),
toFilter = Date.IsInPreviousNWeeks(DateTime.AddZone(toDatetime, 0), 8)
in toFilter
)
in filterDates
Приведенный выше код может быть функциональным (надеюсь), но концептуально это может быть неправильный способ сделать это. Я не знаком с этой функцией DocumentDB.Contents
, но эта ссылка (https://www.powerquery.io/accessing-data/document-db/documentdb.contents ) предполагает, что он имеет следующие параметры:
функция (url в виде текста, необязательная база данных как обнуляемая any, необязательная коллекция как обнуляемая any, необязательные параметры как обнуляемая запись) в виде таблицы
и далее говорится:
если запрос поля указан в записи параметров, будут возвращены результаты запроса, выполняемого в указанной базе данных и / или коллекции.
Я понимаю, что это означает, что если вы измените свою первую строку на что-то вроде:
Source = DocumentDB.Contents("https://xxx.xxx", "xxx", "xxx", [Query = "..."])
если указанный вами запрос "..."
будет понят сервером (предположим, что запрос должен быть на родном языке запросов Cosmos DB), вам будут возвращены данные только за последние 8 недель (что означает, что требуется меньше данных для отправки и меньше работы для вас).). Как я уже сказал, я не знаком с Azure Cosmos DB, поэтому я не могу комментировать дальше. Но это кажется лучшим способом сделать это.