当系统参数为空时的 PyMongo AND 条件
PyMongo AND condition when system argument is null
我正在使用 PHP 将系统参数传递给 PyMongo 以获取数据。我有多个系统参数。例如:
PHP
$Vdat = ["Company1", "Company2"];
$Market = ['Market1','Market2'];
$pyexecdb = "/usr/bin/python3 getdata.py " . base64_encode(json_encode($Vdat)) . " " . base64_encode(json_encode($Market));
PyMongo
from pymongo import MongoClient
import urllib.parse
import pandas as pd
from pandas import DataFrame
import json,sys
import base64
username = urllib.parse.quote_plus('uid')
password = urllib.parse.quote_plus('pwd')
client = MongoClient('mongodb://%s:%s@ipaddress:27017' % (username, password))
db = client['db']
col = db['collection']
Vdata = json.loads(base64.b64decode(sys.argv[1]))
vdat = eval(Vdata)
Market = json.loads(base64.b64decode(sys.argv[2]))
market = eval(Market)
ndf = col.find({ "$and": [ { "VendorName": {"$in": vdat } },{ "City": {"$in": market} } ]})
示例数据
{
"_id": ObjectId("5eff011c7cbc297f7122d9cc"),
"SrlNo": "72808",
"VendorCode": "V000246",
"VendorName": “Company1",
"City": “Market1”
},
{
"_id": ObjectId("5eff011c7cbc297f7122d9cb"),
"SrlNo": "72809",
"VendorCode": "V000247",
"VendorName": “Company2",
"City": “Market2"
}
这在 vdat
和 market
值都可用时效果很好。但是,在许多情况下,我将只有 vdat 或市场。有没有一种方法可以 运行 上面的 col.find
和 and
条件,即使 sys.argv 之一为空。我有很多 sys.argv,因此如果排除条件,可以写多个。
我知道我们可以在 mongodb 中使用 $ifnull
和 $unwind
参数,但不确定如何在这种情况下使用它们。
预期输出
即使变量 vdat
或 market
之一为 null
,预期输出也是 运行 以下查询
例子
ndf = col.find({ "$and": [ { "VendorName": {"$in": vdat } },{ "City": {"$in": market} } ]})
我首先将您的输入设为单个 JSON arg。这将避免命令行上潜在的空白问题,并在将来为您提供更多的灵活性来处理额外的参数。
python3 '{"vdat":["company1","company2"], "mkt":["market1","market2"]}'
接下来,由于您希望将命令行参数与查询中的实际字段名称分开但保持动态,请使用如下映射器:
arg_items = json.loads(argv[1])
argmap = {
"vdat":"VendorName",
"mkt":"City"
}
andlist = []
for k, v in argmap.items():
if k in arg_items:
andlist.append({v: {"$in": arg_items[k]}})
if len(andlist) > 0: # make sure we picked up at least 1 thing from command line:
ndf = col.find({ "$and": andlist })
我正在使用 PHP 将系统参数传递给 PyMongo 以获取数据。我有多个系统参数。例如:
PHP
$Vdat = ["Company1", "Company2"];
$Market = ['Market1','Market2'];
$pyexecdb = "/usr/bin/python3 getdata.py " . base64_encode(json_encode($Vdat)) . " " . base64_encode(json_encode($Market));
PyMongo
from pymongo import MongoClient
import urllib.parse
import pandas as pd
from pandas import DataFrame
import json,sys
import base64
username = urllib.parse.quote_plus('uid')
password = urllib.parse.quote_plus('pwd')
client = MongoClient('mongodb://%s:%s@ipaddress:27017' % (username, password))
db = client['db']
col = db['collection']
Vdata = json.loads(base64.b64decode(sys.argv[1]))
vdat = eval(Vdata)
Market = json.loads(base64.b64decode(sys.argv[2]))
market = eval(Market)
ndf = col.find({ "$and": [ { "VendorName": {"$in": vdat } },{ "City": {"$in": market} } ]})
示例数据
{
"_id": ObjectId("5eff011c7cbc297f7122d9cc"),
"SrlNo": "72808",
"VendorCode": "V000246",
"VendorName": “Company1",
"City": “Market1”
},
{
"_id": ObjectId("5eff011c7cbc297f7122d9cb"),
"SrlNo": "72809",
"VendorCode": "V000247",
"VendorName": “Company2",
"City": “Market2"
}
这在 vdat
和 market
值都可用时效果很好。但是,在许多情况下,我将只有 vdat 或市场。有没有一种方法可以 运行 上面的 col.find
和 and
条件,即使 sys.argv 之一为空。我有很多 sys.argv,因此如果排除条件,可以写多个。
我知道我们可以在 mongodb 中使用 $ifnull
和 $unwind
参数,但不确定如何在这种情况下使用它们。
预期输出
即使变量 vdat
或 market
之一为 null
例子
ndf = col.find({ "$and": [ { "VendorName": {"$in": vdat } },{ "City": {"$in": market} } ]})
我首先将您的输入设为单个 JSON arg。这将避免命令行上潜在的空白问题,并在将来为您提供更多的灵活性来处理额外的参数。
python3 '{"vdat":["company1","company2"], "mkt":["market1","market2"]}'
接下来,由于您希望将命令行参数与查询中的实际字段名称分开但保持动态,请使用如下映射器:
arg_items = json.loads(argv[1])
argmap = {
"vdat":"VendorName",
"mkt":"City"
}
andlist = []
for k, v in argmap.items():
if k in arg_items:
andlist.append({v: {"$in": arg_items[k]}})
if len(andlist) > 0: # make sure we picked up at least 1 thing from command line:
ndf = col.find({ "$and": andlist })