我正在运行PySpark,并且已经设置了MongoDB连接器以访问数据库。我正在尝试建立一个管道,其中$ match阶段包括按日期过滤。我无法完成这项工作,这里可能需要类似ISODATE(“”)的东西。
我已经尝试使用正确格式的datetime对象,并且还尝试在$ match阶段传递isoformat字符串。这些都不起作用。
mongoURI = "mongodb://localhost/databaseName.collection"
my_spark = SparkSession.builder.master("local").appName("test").config("spark.mongodb.input.uri", mongoURI).getOrCreate()
from_date = datetime.datetime(2018, 1, 1)
to_date = datetime.datetime(2018, 1, 1)
products =['P1', 'P2']
clients = ['C1', 'C2']
pipeline = [
{'$match': {'$and': [ { '_created_at': { '$gt': from_date } }, { '_created_at': { '$lt': to_date } } ],'product': {'$in': products},'client': {'$in':clients }}},
{'$project': {'product': 1,'client': 1}}]
df = my_spark.read.format("com.mongodb.spark.sql.DefaultSource").option("pipeline", pipeline).load()
print(df.printSchema())
我希望找回一些文件,但我却收到此错误
Py4JJavaError: An error occurred while calling o36.load.: java.lang.IllegalArgumentException: requirement failed: Invalid Aggregation map Map ...
It should be a list of pipeline stages (Documents) or a single pipeline stage (Document)
如果我将日期作为字符串传递,则会得到一个None模式,而当排除查询中基于日期的部分时,则会得到文档。因此,就是那部分出现了问题。
答案 0 :(得分:0)
问题在于您的日期中的日期from_date和to_date是您将它们以变量形式传递给管道时,PySpark不采用您为ISO日期定义的格式。那就是它失败的原因,但是错误并不能说明问题。
下面是通过将日期转换为ISO日期然后传递到管道的解决方法:
from_date = datetime.datetime(2018, 1, 1)
print(type(from_date ))
>> <type 'datetime.datetime'>
from_date = from_date.isoformat()
from_date = from_date+"Z"
print(from_date)
>> 2018-01-01T00:00:00Z
这是应该完成的转换,然后将变量传递到管道的方法
pipeline = [{'$match': {'$and': [ { '_created_at': { '$gt': from_date } }, { '_created_at': { '$lt': to_date } } ],'product': {'$in': products},'client': {'$in':clients }}},{'$project': {'product': 1,'client': 1}}]