当系统参数为空时的 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"
}

这在 vdatmarket 值都可用时效果很好。但是,在许多情况下,我将只有 vdat 或市场。有没有一种方法可以 运行 上面的 col.findand 条件,即使 sys.argv 之一为空。我有很多 sys.argv,因此如果排除条件,可以写多个。

我知道我们可以在 mongodb 中使用 $ifnull$unwind 参数,但不确定如何在这种情况下使用它们。

预期输出

即使变量 vdatmarket 之一为 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 })