Search on multiple collections in MongoDB

前端 未结 7 1972
自闭症患者
自闭症患者 2020-12-01 01:28

I know the theory of MongoDB and the fact that is doesn\'t support joins, and that I should use embeded documents or denormalize as much as possible, but here goes:

7条回答
  •  一向
    一向 (楼主)
    2020-12-01 01:54

    Based on @brian-moquin and others, I made a set of functions to search entire collections with entire keys(fields) by simple keyword.

    It's in my gist; https://gist.github.com/fkiller/005dc8a07eaa3321110b3e5753dda71b

    For more detail, I first made a function to gather all keys.

    function keys(collectionName) {
        mr = db.runCommand({
            'mapreduce': collectionName,
            'map': function () {
                for (var key in this) { emit(key, null); }
            },
            'reduce': function (key, stuff) { return null; },
            'out': 'my_collection' + '_keys'
        });
        return db[mr.result].distinct('_id');
    }
    

    Then one more to generate $or query from keys array.

    function createOR(fieldNames, keyword) {
        var query = [];
        fieldNames.forEach(function (item) {
            var temp = {};
            temp[item] = { $regex: '.*' + keyword + '.*' };
            query.push(temp);
        });
        if (query.length == 0) return false;
        return { $or: query };
    }
    

    Below is a function to search a single collection.

    function findany(collection, keyword) {
        var query = createOR(keys(collection.getName()));
        if (query) {
            return collection.findOne(query, keyword);
        } else {
            return false;
        }
    }
    

    And, finally a search function for every collections.

    function searchAll(keyword) {
        var all = db.getCollectionNames();
        var results = [];
        all.forEach(function (collectionName) {
            print(collectionName);
            if (db[collectionName]) results.push(findany(db[collectionName], keyword));
        });
        return results;
    }
    

    You can simply load all functions in Mongo console, and execute searchAll('any keyword')

提交回复
热议问题