【问题标题】:PyMongo AND condition when system argument is null系统参数为空时的 PyMongo AND 条件
【发布时间】:2020-07-15 21:59:05
【问题描述】:

我正在使用 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 或市场。有没有一种方法可以在and 条件下运行上述col.find,即使其中一个sys.argv 为空。我有很多 sys.argv,因此如果排除条件,则可以编写多个。

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

预期输出

即使变量vdatmarket 之一为空,预期的输出是运行以下查询

示例

ndf = col.find({ "$and": [ { "VendorName": {"$in": vdat } },{ "City": {"$in": market} } ]})

【问题讨论】:

  • 您能添加您的示例文档和预期输出吗?
  • @Gibbs 添加了示例数据

标签: mongodb find pymongo


【解决方案1】:

我首先将您的输入设为单个 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 })                                             

【讨论】:

  • 非常感谢...您的解决方案帮助我解决了许多问题。
猜你喜欢
  • 2014-02-09
  • 2018-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-01
  • 1970-01-01
相关资源
最近更新 更多