1

マージする必要があるリレーショナル データを含む複数の json ファイルがあります。各ファイルには、すべてのファイルの共通キーである commonkey を持つレコードがあります。以下の例では、a0 、a1 は共通キーです。値は、複数のネストされたディクショナリです。 Key1、key2 などのキーを以下に示すように、複数の json ファイルをマージし、dboutput.json に示すように出力を取得する必要があります。ファイル名はマージ操作のインデックスとして機能します。このような質問は、失われた情報をマージする関連する質問ですが、私の場合、既存のキーを置き換えるか、更新をスキップする更新は必要ありません。既存のキーをヒットすると、ファイル名でインデックス付けされた別のネストされた辞書が作成されます。

例:

ファイル db1.json:

"a0": {
        "共通鍵": [
            "a1"、
            「親キー値1」
        ]、
        "key1": "kvalue1",
        "key2": "kvalue2"
        "keyp": "kvalue2abc"

    }、
"a1": {
...
}

ファイル db2.json:

"a0": {
        "共通鍵": [
            "a1"、
            「親キー値1」
        ]、
        "key1": "kvalue1xyz",
        "key2": "kvalue2",
        "key3": "kvalue2"



    }、

"a1": {
...
}

望ましい出力

ファイル dboutput.json

"a0": {
        "共通鍵": [
            "a1"、
            「親キー値1」
        ]、
        "key1": {"db1":"kvalue1","db2":"kvalue1xyz"} ,
        "key2": {"db1":"kvalue2","db2":"kvalue2"} ,
        "key3": {"db2":"kvalue2"}
        "keyp": {"db1":"kvalue2abc"}



    }、
"a1": {
...
}

では、このようなロスレス マージを行うにはどうすればよいでしょうか。"key2": {"db1":"kvalue2","db2":"kvalue2"} に注意してください。キーと値のペアが同じであっても、別々に保存する必要があります。実際には、出力はすべての入力ファイルの結合であり、他のすべてのファイルからのすべてのエントリが含まれています。

また

"commonkey": [
            "a1", 
            "parentkeyvalue1"
        ],

すべてのファイルで同じになるため、繰り返す必要はありません

4

2 に答える 2

2

私はついにそれを手に入れることができました:

class NestedDict(collections.OrderedDict):
    """Implementation of perl's autovivification feature."""
    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value

def mergejsons(jsns):
 ##use auto vification Nested Dict
    op=nesteddict.NestedDict()
    for j in jsns:
        jdata=json.load(open(j))
        jname=j.split('.')[0][-2:]
        for commnkey,val in jdata.items():
            for k,v in val.items():
                if k!='commonkey':
                    op[commnkey][k][jname]=v
                if  op[commnkey].has_key('commonkey'):
                    continue
                else:
                    op[commnkey][k][jname]=v
于 2013-10-02T14:09:00.933 に答える
1

簡単な解決策は、各 JSON オブジェクトを反復処理し、表示されるとおりに各「共通キー」に辞書のペアを追加することです。各 JSON ファイルをリストにロードし、それらを繰り返しマージする例を次に示します。

#!/usr/bin/python
import json

# Hardcoded list of JSON files
dbs = [ "db1.json", "db2.json" ]
output = dict() # stores all the merged output

for db in dbs:
    # Name the JSON obj and load it 
    db_name = db.split(".json")[0]
    obj = json.load(open(db))

    # Iterate through the common keys, adding them only if they're new
    for common_key, data in obj.items():
        if common_key not in output:
            output[common_key] = dict(commonkey=data["commonkey"])

        # Within each common key, add key, val pairs 
        # subindexed by the database name
        for key, val in data.items():
            if key != "commonkey":
                if key in output[common_key]:
                    output[common_key][key][db_name] = val
                else:
                    output[common_key][key] = {db_name: val}


# Output resulting json to file
open("dboutput.json", "w").write( 
    json.dumps( output, sort_keys=True, indent=4, separators=(',', ': ') )
)
于 2013-10-02T13:28:47.427 に答える