รับชื่อของคีย์ทั้งหมดในคอลเลกชัน


322

ฉันต้องการรับชื่อของคีย์ทั้งหมดในคอลเลกชัน MongoDB

ตัวอย่างเช่นจากสิ่งนี้:

db.things.insert( { type : ['dog', 'cat'] } );
db.things.insert( { egg : ['cat'] } );
db.things.insert( { type : [] } );
db.things.insert( { hello : []  } );

ฉันต้องการรับกุญแจพิเศษ:

type, egg, hello

คำตอบ:


346

คุณสามารถทำได้ด้วย MapReduce:

mr = db.runCommand({
  "mapreduce" : "my_collection",
  "map" : function() {
    for (var key in this) { emit(key, null); }
  },
  "reduce" : function(key, stuff) { return null; }, 
  "out": "my_collection" + "_keys"
})

จากนั้นเรียกใช้คอลเลกชันที่เกิดขึ้นเพื่อค้นหาคีย์ทั้งหมด:

db[mr.result].distinct("_id")
["foo", "bar", "baz", "_id", ...]

2
สวัสดี! ฉันเพิ่งโพสต์ติดตามคำถามนี้เพื่อถามว่าจะทำให้ส่วนย่อยนี้ทำงานอย่างไรแม้จะมีปุ่มที่อยู่ในระดับลึกลงไปในโครงสร้างข้อมูล ( stackoverflow.com/questions/2997004/… )
Andrea Fiore

1
@ Kristina: เป็นไปได้อย่างไรที่ฉันได้รับรายการทั้งหมดที่มีคีย์เมื่อใช้สิ่งนี้ในการเก็บสิ่งต่างๆ มันมีลักษณะที่เกี่ยวข้องกับกลไกประวัติศาสตร์เพราะผมได้รับสิ่งที่ฉันได้แก้ไขในอดีต ..
Shawn

3
ฉันรู้ว่านี่เป็นหัวข้อเก่า แต่ฉันดูเหมือนจะมีความต้องการที่คล้ายกัน ฉันใช้ไดรเวอร์พื้นเมือง nodejs mongodb การรวบรวมชั่วคราวที่เกิดขึ้นดูเหมือนจะว่างเปล่าเสมอ ฉันใช้ฟังก์ชัน mapreduce ในคลาสคอลเลคชันสำหรับสิ่งนี้ เป็นไปไม่ได้เหรอ?
Deepak

6
นี้อาจจะเป็นที่เห็นได้ชัด แต่ถ้าคุณต้องการที่จะได้รับรายชื่อของทุกคีย์ไม่ซ้ำกันในเอกสารย่อยเป็นเพียงแค่ปรับเปลี่ยนบรรทัดนี้:for (var key in this.first_level.second_level.nth_level) { emit(key, null); }
dtbarne

3
แทนที่จะบันทึกลงในคอลเล็กชันจากนั้นเรียกใช้งานที่แตกต่างกันฉันใช้แผนที่ ():db.runCommand({..., out: { "inline" : 1 }}).results.map(function(i) { return i._id; });
Ian Stanley

203

ด้วยคำตอบของ Kristina ในฐานะที่เป็นแรงบันดาลใจฉันได้สร้างเครื่องมือโอเพนซอร์สที่ชื่อว่า Variety ซึ่งทำสิ่งนี้: https://github.com/variety/variety


13
นี่เป็นเครื่องมือที่ยอดเยี่ยมขอแสดงความยินดี มันทำสิ่งที่คำถามถามและสามารถกำหนดค่าด้วยขีด จำกัด ความลึก ฯลฯ แนะนำโดยใครก็ตามที่ติดตาม
Paul Biggar

74

คุณสามารถใช้การรวมกับเวอร์ชันใหม่$objectToArrrayใน3.4.4การแปลงคู่คีย์และค่าทั้งหมดลงในอาร์เรย์เอกสารตามด้วย$unwind& $group ด้วย$addToSetเพื่อรับคีย์ที่แตกต่างกันในคอลเลกชันทั้งหมด

$$ROOT สำหรับการอ้างอิงเอกสารระดับบนสุด

db.things.aggregate([
  {"$project":{"arrayofkeyvalue":{"$objectToArray":"$$ROOT"}}},
  {"$unwind":"$arrayofkeyvalue"},
  {"$group":{"_id":null,"allkeys":{"$addToSet":"$arrayofkeyvalue.k"}}}
])

คุณสามารถใช้แบบสอบถามด้านล่างเพื่อรับกุญแจในเอกสารเดียว

db.things.aggregate([
  {"$match":{_id: "5e8f968639bb8c67726686bc"}}, /* Replace with the document's ID */
  {"$project":{"arrayofkeyvalue":{"$objectToArray":"$$ROOT"}}},
  {"$project":{"keys":"$arrayofkeyvalue.k"}}
])

20
นี่เป็นคำตอบที่ดีที่สุดจริงๆ แก้ไขปัญหาโดยไม่ต้องมีภาษาโปรแกรมหรือแพ็คเกจอื่น ๆ และทำงานร่วมกับไดรเวอร์ทั้งหมดที่รองรับเฟรมเวิร์กรวม (แม้แต่ Meteor!)
Micah Henning

2
หากคุณต้องการส่งคืนอาร์เรย์แทนเคอร์เซอร์ที่มีรายการแผนที่เดียวด้วยปุ่ม "allkeys" คุณสามารถผนวก.next()["allkeys"]คำสั่ง (สมมติว่าการรวบรวมมีองค์ประกอบอย่างน้อยหนึ่งองค์ประกอบ)
M. Justin

19

ลองสิ่งนี้:

doc=db.thinks.findOne();
for (key in doc) print(key);

49
คำตอบที่ไม่ถูกต้องเนื่องจากจะแสดงเฉพาะฟิลด์สำหรับเอกสารเดี่ยวในคอลเล็กชัน - ฟิลด์อื่นอาจทั้งหมดมีคีย์ที่แตกต่างกันโดยสิ้นเชิง
Asya Kamsky

15
มันยังคงเป็นคำตอบที่มีประโยชน์ที่สุดสำหรับฉันเป็นขั้นต่ำที่เรียบง่ายพอสมควร
Boris Burkov

11
มันไม่มีประโยชน์หรอกเหรอ? มันจะมีประโยชน์อย่างไรถ้ามันให้คำตอบที่ผิดกับคุณ?
Zlatko

4
บริบทแสดงสิ่งที่มีประโยชน์: หากข้อมูลถูกทำให้เป็นมาตรฐาน (เช่น origen จากไฟล์ CSV) จะมีประโยชน์ ... สำหรับข้อมูลที่นำเข้าจาก SQL นั้นมีประโยชน์
Peter Krauss

5
มันไม่ใช่คำตอบที่ดีมันเป็นคำตอบเกี่ยวกับวิธีการรับกุญแจขององค์ประกอบหนึ่งในคอลเลกชันไม่ใช่กุญแจทั้งหมดในคอลเลกชัน!
yonatan

16

หากคอลเลกชันเป้าหมายของคุณไม่ใหญ่เกินไปคุณสามารถลองทำสิ่งนี้ได้ภายใต้ mongo shell client:

var allKeys = {};

db.YOURCOLLECTION.find().forEach(function(doc){Object.keys(doc).forEach(function(key){allKeys[key]=1})});

allKeys;

ที่นี่ฉันจะให้ regExp สำหรับคีย์เฉพาะถ้าฉันต้องการดูได้อย่างไร
TB.M

@ TB.M คุณสามารถลอง: db.configs.find (). forEach (ฟังก์ชั่น (doc) {Object.keys (doc) .forEach (ฟังก์ชั่น (กุญแจ) {ถ้า (/YOURREGEXP/.test(key)) { AllKeys [สำคัญ] = 1}})});
Li Chunlin

การทดสอบหมายถึงอะไรที่นี่? คุณช่วยอธิบายได้ไหม
TB.M


14

วิธีทำความสะอาดและนำกลับมาใช้ซ้ำได้โดยใช้ pymongo:

from pymongo import MongoClient
from bson import Code

def get_keys(db, collection):
    client = MongoClient()
    db = client[db]
    map = Code("function() { for (var key in this) { emit(key, null); } }")
    reduce = Code("function(key, stuff) { return null; }")
    result = db[collection].map_reduce(map, reduce, "myresults")
    return result.distinct('_id')

การใช้งาน:

get_keys('dbname', 'collection')
>> ['key1', 'key2', ... ]

1
ใช้งานได้ดี ในที่สุดได้รับการแก้ไขปัญหาของฉัน .... นี่คือทางออกที่ง่ายที่สุดที่ฉันเห็นในกองมากล้น ..
Smack Alpha

และตัวกรองโดยแบ่งตามชนิดเพียงแค่เพิ่มเช่นก่อนif (typeof(this[key]) == 'number') emit(key, null)
Skippy le Grand Gourou

10

ใช้หลาม ส่งคืนชุดของคีย์ระดับบนสุดทั้งหมดในคอลเลกชัน:

#Using pymongo and connection named 'db'

reduce(
    lambda all_keys, rec_keys: all_keys | set(rec_keys), 
    map(lambda d: d.keys(), db.things.find()), 
    set()
)

1
ฉันพบสิ่งนี้เพื่อการทำงาน แต่มีประสิทธิภาพเมื่อเปรียบเทียบกับการสอบถาม Mongo raw หรือไม่
พระเยซูโกเมซ

1
ฉันค่อนข้างแน่ใจว่านี่ไม่มีประสิทธิภาพมากเมื่อเทียบกับการทำสิ่งนี้โดยตรงใน Mongodb
Ingo Fischer

9

นี่คือตัวอย่างที่ใช้งานได้ใน Python: ตัวอย่างนี้ส่งคืนผลลัพธ์แบบอินไลน์

from pymongo import MongoClient
from bson.code import Code

mapper = Code("""
    function() {
                  for (var key in this) { emit(key, null); }
               }
""")
reducer = Code("""
    function(key, stuff) { return null; }
""")

distinctThingFields = db.things.map_reduce(mapper, reducer
    , out = {'inline' : 1}
    , full_response = True)
## do something with distinctThingFields['results']

9

หากคุณใช้ mongodb 3.4.4 ขึ้นไปคุณสามารถใช้การรวม$objectToArrayและการ$groupรวมด้านล่าง

db.collection.aggregate([
  { "$project": {
    "data": { "$objectToArray": "$$ROOT" }
  }},
  { "$project": { "data": "$data.k" }},
  { "$unwind": "$data" },
  { "$group": {
    "_id": null,
    "keys": { "$addToSet": "$data" }
  }}
])

นี่คือตัวอย่างการทำงาน


นี่คือคำตอบที่ดีที่สุด คุณยังสามารถใช้$matchที่จุดเริ่มต้นของขั้นตอนการรวมเพื่อรับกุญแจของเอกสารที่ตรงกับเงื่อนไขเท่านั้น
RonquilloAeon

5

ฉันประหลาดใจไม่มีใครที่นี่มี ans โดยใช้ง่ายjavascriptและSetตรรกะเพื่อกรองค่าซ้ำโดยอัตโนมัติตัวอย่างง่าย ๆ ในเปลือก Mongoดังต่อไปนี้:

var allKeys = new Set()
db.collectionName.find().forEach( function (o) {for (key in o ) allKeys.add(key)})
for(let key of allKeys) print(key)

นี้จะพิมพ์ที่ไม่ซ้ำกันเป็นไปได้ทั้งหมดคีย์ในชื่อคอลเลกชัน: collectionName


3

มันใช้งานได้ดีสำหรับฉัน:

var arrayOfFieldNames = [];

var items = db.NAMECOLLECTION.find();

while(items.hasNext()) {
  var item = items.next();
  for(var index in item) {
    arrayOfFieldNames[index] = index;
   }
}

for (var index in arrayOfFieldNames) {
  print(index);
}

3

ผมคิดว่าวิธีที่ดีที่สุดทำเช่นนี้เป็นที่กล่าวถึงที่นี่อยู่ใน mongod 3.4.4+ แต่โดยไม่ต้องใช้$unwindผู้ประกอบการและใช้เพียงสองขั้นตอนในท่อ แต่เราสามารถใช้ตัวดำเนินการ$mergeObjectsและ$objectToArray

ใน$groupขั้นตอนนี้เราใช้$mergeObjectsโอเปอเรเตอร์เพื่อส่งคืนเอกสารเดียวโดยที่คีย์ / ค่ามาจากเอกสารทั้งหมดในคอลเล็กชัน

จากนั้นมาถึงจุด$projectที่เราใช้$mapและ$objectToArrayเพื่อส่งคืนกุญแจ

let allTopLevelKeys =  [
    {
        "$group": {
            "_id": null,
            "array": {
                "$mergeObjects": "$$ROOT"
            }
        }
    },
    {
        "$project": {
            "keys": {
                "$map": {
                    "input": { "$objectToArray": "$array" },
                    "in": "$$this.k"
                }
            }
        }
    }
];

ตอนนี้ถ้าเรามีเอกสารซ้อนกันและต้องการได้รับกุญแจเช่นกันสิ่งนี้สามารถทำได้ เพื่อความง่ายให้พิจารณาเอกสารที่มีเอกสารแบบฝังที่มีลักษณะดังนี้

{field1: {field2: "abc"}, field3: "def"}
{field1: {field3: "abc"}, field4: "def"}

ไพพ์ไลน์ต่อไปนี้จะให้คีย์ทั้งหมด (field1, field2, field3, field4)

let allFistSecondLevelKeys = [
    {
        "$group": {
            "_id": null,
            "array": {
                "$mergeObjects": "$$ROOT"
            }
        }
    },
    {
        "$project": {
            "keys": {
                "$setUnion": [
                    {
                        "$map": {
                            "input": {
                                "$reduce": {
                                    "input": {
                                        "$map": {
                                            "input": {
                                                "$objectToArray": "$array"
                                            },
                                            "in": {
                                                "$cond": [
                                                    {
                                                        "$eq": [
                                                            {
                                                                "$type": "$$this.v"
                                                            },
                                                            "object"
                                                        ]
                                                    },
                                                    {
                                                        "$objectToArray": "$$this.v"
                                                    },
                                                    [
                                                        "$$this"
                                                    ]
                                                ]
                                            }
                                        }
                                    },
                                    "initialValue": [

                                    ],
                                    "in": {
                                        "$concatArrays": [
                                            "$$this",
                                            "$$value"
                                        ]
                                    }
                                }
                            },
                            "in": "$$this.k"
                        }
                    }
                ]
            }
        }
    }
]

ด้วยความพยายามเพียงเล็กน้อยเราสามารถรับกุญแจสำหรับเอกสารย่อยทั้งหมดในเขตข้อมูลอาร์เรย์ที่องค์ประกอบเป็นวัตถุได้เช่นกัน


ใช่$unwindจะระเบิดคอลเลคชั่น (ฟิลด์จำนวน * ไม่มีเอกสาร) เราสามารถหลีกเลี่ยงได้โดยใช้$mergeObjectsกับทุกรุ่น> 3.6.. ทำเช่นเดียวกันควรเคยเห็นคำตอบนี้มาก่อนชีวิตของฉันจะง่ายขึ้น ( -_-)
whoami

3

อาจไม่ได้อยู่ในหัวข้อเล็กน้อย แต่คุณสามารถพิมพ์คีย์ / ฟิลด์ทั้งหมดซ้ำ ๆ ของวัตถุ:

function _printFields(item, level) {
    if ((typeof item) != "object") {
        return
    }
    for (var index in item) {
        print(" ".repeat(level * 4) + index)
        if ((typeof item[index]) == "object") {
            _printFields(item[index], level + 1)
        }
    }
}

function printFields(item) {
    _printFields(item, 0)
}

มีประโยชน์เมื่อวัตถุทั้งหมดในคอลเลกชันมีโครงสร้างเดียวกัน


1

ในการรับรายการคีย์ทั้งหมดลบ_idให้ลองเรียกใช้ไพพ์ไลน์รวมต่อไปนี้:

var keys = db.collection.aggregate([
    { "$project": {
       "hashmaps": { "$objectToArray": "$$ROOT" } 
    } }, 
    { "$project": {
       "fields": "$hashmaps.k"
    } },
    { "$group": {
        "_id": null,
        "fields": { "$addToSet": "$fields" }
    } },
    { "$project": {
            "keys": {
                "$setDifference": [
                    {
                        "$reduce": {
                            "input": "$fields",
                            "initialValue": [],
                            "in": { "$setUnion" : ["$$value", "$$this"] }
                        }
                    },
                    ["_id"]
                ]
            }
        }
    }
]).toArray()[0]["keys"];

0

ฉันพยายามเขียนใน nodejs และสุดท้ายมานี้:

db.collection('collectionName').mapReduce(
function() {
    for (var key in this) {
        emit(key, null);
    }
},
function(key, stuff) {
    return null;
}, {
    "out": "allFieldNames"
},
function(err, results) {
    var fields = db.collection('allFieldNames').distinct('_id');
    fields
        .then(function(data) {
            var finalData = {
                "status": "success",
                "fields": data
            };
            res.send(finalData);
            delteCollection(db, 'allFieldNames');
        })
        .catch(function(err) {
            res.send(err);
            delteCollection(db, 'allFieldNames');
        });
 });

หลังจากอ่านคอลเล็กชันที่สร้างขึ้นใหม่ "allFieldNames" ให้ลบออก

db.collection("allFieldNames").remove({}, function (err,result) {
     db.close();
     return; 
});

0

ตามเอกสาร mongoldb การรวมกันของdistinct

ค้นหาค่าที่แตกต่างสำหรับเขตข้อมูลที่ระบุในคอลเล็กชันหรือมุมมองเดียวและส่งคืนผลลัพธ์ในอาร์เรย์

และการดำเนินการรวบรวมดัชนีเป็นสิ่งที่จะส่งกลับค่าที่เป็นไปได้ทั้งหมดสำหรับคีย์ที่กำหนดหรือดัชนี:

ส่งคืนอาร์เรย์ที่มีรายการเอกสารที่ระบุและอธิบายดัชนีที่มีอยู่ในการรวบรวม

ดังนั้นในวิธีการที่กำหนดเราสามารถใช้วิธีการดังต่อไปนี้ในการค้นหาคอลเลกชันสำหรับดัชนีที่ลงทะเบียนแล้วกลับมาพูดวัตถุที่มีดัชนีสำหรับคีย์ (ตัวอย่างนี้ใช้ async / await สำหรับ NodeJS แต่ เห็นได้ชัดว่าคุณสามารถใช้วิธีอะซิงโครนัสอื่น ๆ ได้):

async function GetFor(collection, index) {

    let currentIndexes;
    let indexNames = [];
    let final = {};
    let vals = [];

    try {
        currentIndexes = await collection.indexes();
        await ParseIndexes();
        //Check if a specific index was queried, otherwise, iterate for all existing indexes
        if (index && typeof index === "string") return await ParseFor(index, indexNames);
        await ParseDoc(indexNames);
        await Promise.all(vals);
        return final;
    } catch (e) {
        throw e;
    }

    function ParseIndexes() {
        return new Promise(function (result) {
            let err;
            for (let ind in currentIndexes) {
                let index = currentIndexes[ind];
                if (!index) {
                    err = "No Key For Index "+index; break;
                }
                let Name = Object.keys(index.key);
                if (Name.length === 0) {
                    err = "No Name For Index"; break;
                }
                indexNames.push(Name[0]);
            }
            return result(err ? Promise.reject(err) : Promise.resolve());
        })
    }

    async function ParseFor(index, inDoc) {
        if (inDoc.indexOf(index) === -1) throw "No Such Index In Collection";
        try {
            await DistinctFor(index);
            return final;
        } catch (e) {
            throw e
        }
    }
    function ParseDoc(doc) {
        return new Promise(function (result) {
            let err;
            for (let index in doc) {
                let key = doc[index];
                if (!key) {
                    err = "No Key For Index "+index; break;
                }
                vals.push(new Promise(function (pushed) {
                    DistinctFor(key)
                        .then(pushed)
                        .catch(function (err) {
                            return pushed(Promise.resolve());
                        })
                }))
            }
            return result(err ? Promise.reject(err) : Promise.resolve());
        })
    }

    async function DistinctFor(key) {
        if (!key) throw "Key Is Undefined";
        try {
            final[key] = await collection.distinct(key);
        } catch (e) {
            final[key] = 'failed';
            throw e;
        }
    }
}

ดังนั้นการสืบค้นคอลเลกชันที่มี_idดัชนีพื้นฐานจะส่งคืนสิ่งต่อไปนี้ (การรวบรวมการทดสอบมีเพียงเอกสารเดียวในเวลาที่ทำการทดสอบ):

Mongo.MongoClient.connect(url, function (err, client) {
    assert.equal(null, err);

    let collection = client.db('my db').collection('the targeted collection');

    GetFor(collection, '_id')
        .then(function () {
            //returns
            // { _id: [ 5ae901e77e322342de1fb701 ] }
        })
        .catch(function (err) {
            //manage your error..
        })
});

โปรดทราบว่าวิธีนี้ใช้เมธอดดั้งเดิมของไดรเวอร์ NodeJS ตามคำแนะนำอื่น ๆ มีคำแนะนำมีวิธีอื่นเช่นกรอบรวม ฉันพบว่าวิธีนี้มีความยืดหยุ่นมากขึ้นเนื่องจากคุณสามารถสร้างและปรับแต่งวิธีการส่งคืนผลลัพธ์ได้อย่างง่ายดาย เห็นได้ชัดว่านี่เป็นเพียงที่อยู่แอตทริบิวต์ระดับบนสุดไม่ได้อยู่ซ้อนกัน นอกจากนี้เพื่อรับประกันว่าเอกสารทั้งหมดจะเป็นตัวแทนควรจะมีการจัดทำดัชนีรอง (อื่น ๆ กว่า _id หนึ่งหลัก) requiredดัชนีผู้ที่ควรได้รับการกำหนดให้เป็น


0

เราสามารถทำได้โดยใช้ไฟล์ mongo js เพิ่มโค้ดด้านล่างในไฟล์getCollectionName.jsของคุณและรันไฟล์ js ในคอนโซลของ Linux ดังที่ระบุด้านล่าง:

mongo - โฮสต์ 192.168.1.135 getCollectionName.js

db_set = connect("192.168.1.135:27017/database_set_name"); // for Local testing
// db_set.auth("username_of_db", "password_of_db"); // if required

db_set.getMongo().setSlaveOk();

var collectionArray = db_set.getCollectionNames();

collectionArray.forEach(function(collectionName){

    if ( collectionName == 'system.indexes' || collectionName == 'system.profile' || collectionName == 'system.users' ) {
        return;
    }

    print("\nCollection Name = "+collectionName);
    print("All Fields :\n");

    var arrayOfFieldNames = []; 
    var items = db_set[collectionName].find();
    // var items = db_set[collectionName].find().sort({'_id':-1}).limit(100); // if you want fast & scan only last 100 records of each collection
    while(items.hasNext()) {
        var item = items.next(); 
        for(var index in item) {
            arrayOfFieldNames[index] = index;
        }
    }
    for (var index in arrayOfFieldNames) {
        print(index);
    }

});

quit();

ขอบคุณ @ackuser


0

การติดตามกระทู้จากคำตอบของ @James Cropcho ฉันได้ใช้สิ่งต่อไปนี้ซึ่งฉันพบว่าใช้งานง่ายสุด ๆ มันเป็นเครื่องมือที่ไบนารีซึ่งเป็นสิ่งที่ผมกำลังมองหา: mongoeye

ใช้เครื่องมือนี้ใช้เวลาประมาณ 2 นาทีเพื่อให้สคีมาของฉันส่งออกจากบรรทัดคำสั่ง


0

ฉันรู้ว่าคำถามนี้มีอายุ 10 ปี แต่ไม่มีวิธีแก้ปัญหา C # และนี่ใช้เวลาหลายชั่วโมงในการคิดออก ฉันใช้ไดรเวอร์. NET และSystem.Linqส่งคืนรายการคีย์

var map = new BsonJavaScript("function() { for (var key in this) { emit(key, null); } }");
var reduce = new BsonJavaScript("function(key, stuff) { return null; }");
var options = new MapReduceOptions<BsonDocument, BsonDocument>();
var result = await collection.MapReduceAsync(map, reduce, options);
var list = result.ToEnumerable().Select(item => item["_id"].ToString());

-1

ฉันขยายวิธีแก้ปัญหาของ Carlos LM ออกไปเล็กน้อย

ตัวอย่างของสคีมา:

var schema = {
    _id: 123,
    id: 12,
    t: 'title',
    p: 4.5,
    ls: [{
            l: 'lemma',
            p: {
                pp: 8.9
            }
        },
         {
            l: 'lemma2',
            p: {
               pp: 8.3
           }
        }
    ]
};

พิมพ์ลงในคอนโซล:

var schemafy = function(schema, i, limit) {
    var i = (typeof i !== 'undefined') ? i : 1;
    var limit = (typeof limit !== 'undefined') ? limit : false;
    var type = '';
    var array = false;

    for (key in schema) {
        type = typeof schema[key];
        array = (schema[key] instanceof Array) ? true : false;

        if (type === 'object') {
            print(Array(i).join('    ') + key+' <'+((array) ? 'array' : type)+'>:');
            schemafy(schema[key], i+1, array);
        } else {
            print(Array(i).join('    ') + key+' <'+type+'>');
        }

        if (limit) {
            break;
        }
    }
}

วิ่ง:

schemafy(db.collection.findOne());

เอาท์พุต

_id <number>
id <number>
t <string>
p <number>
ls <object>:
    0 <object>:
    l <string>
    p <object>:
        pp <number> 

3
คำตอบของเขานั้นผิดและคุณก็สร้างมันขึ้นมา จุดรวมคือการส่งออกทุกสาขาของทุกเอกสารที่ไม่ได้เป็นเอกสารแรกซึ่งอาจจะมีสาขาที่แตกต่างกว่าแต่ละคนต่อไป
Asya Kamsky

-3

ฉันมีวิธีแก้ไขที่ง่ายกว่า 1 ข้อ ...

สิ่งที่คุณสามารถทำได้คือในขณะที่การแทรกข้อมูล / เอกสารลงใน "สิ่ง" คอลเลกชันหลักของคุณคุณต้องแทรกแอตทริบิวต์ใน 1 คอลเลกชันแยกต่างหากให้พูดว่า "Things_attributes"

ดังนั้นทุกครั้งที่คุณแทรก "สิ่ง" คุณจะได้รับจาก "things_attributes" เปรียบเทียบค่าของเอกสารนั้นกับคีย์เอกสารใหม่ของคุณหากมีคีย์ใหม่ปรากฏขึ้นในเอกสารนั้นและใส่ใหม่อีกครั้ง

ดังนั้น Things_attributes จะมีเอกสารของคีย์ที่ไม่ซ้ำกันเพียง 1 ฉบับเท่านั้นซึ่งคุณสามารถหาได้ง่ายเมื่อคุณต้องการโดยใช้ findOne ()


สำหรับฐานข้อมูลที่มีรายการจำนวนมากซึ่งการสืบค้นคีย์ทั้งหมดเป็นประจำและส่วนแทรกไม่บ่อยนักการแคชผลลัพธ์ของข้อความค้นหา "รับกุญแจทั้งหมด" จะสมเหตุสมผล นี่เป็นวิธีหนึ่งในการทำเช่นนั้น
สกอตต์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.