Get the count of Fields in each document through q

2019-08-30 22:29发布

问题:

Is it possible to get the number of fields in document using a Query From MongoDB java Driver

Example:

 Document1 :{_id:1,"type1": 10 "type2":30,"ABC":123,"DEF":345}
 Document2 :{_id:2,"type2":30,"ABC":123,"DEF":345}

Note: In second document "type1" key doesnt exist .

When i project

Is it possible to project only "type1" and "type2" and get number of fields existing in that document.

With current code i am getting all the documents and individually searching if there is the key i am looking is present in the whole cursor: The code snipped is as follows:

MongoClient mcl=new MongoClient();
MongoDatabase mdb=mcl.getDatabase("test");
MongoCollection mcol=mdb.getCollection("testcol");
FindIterable<Document> findIterable = mcol.find();
MongoCursor<Document> cursor = findIterable.iterator();
//Here am having 120 types checking if each type is present..
while(cursor.hasNext())
{

Document doc=cursor.next();
int numberOfTypes=0;
for(int i=1;i<=120;i++)
{
if(doc.containsKey("type"+i))
{
numberOfTypes++;
}
}
System.out.println("*********************************************");
System.out.println("_id"+doc.get("_id"));
    System.out.println("Number of Types in this document are "+numberOfTypes);
System.out.println("*********************************************");
    }

}

This code is working if the records are less it wont be over load to the application ..Suppose there are 5000000 with each Document containing 120 types , the application is crashing as there would be more garbage collection involved as for every iteration we are creating a document.Is there any other approach through which we can achieve the above stated functionality.

回答1:

From your java code I read

project only "type1" and "type2" and get number of fields existing in that document.

as

project only type[1..120] fields and number of such fields in the document

With this assumption, you can map-reduce it as following:

db.testcol.mapReduce(
function(){
    value = {count:0};
    for (i = 1; i <= 120; i++) {
        key = "type" + i
        if (this.hasOwnProperty(key)) {
            value[key] = this[key];
            value.count++
       }
    }
    if (value.count > 0) {
        emit(this._id, value);
    }
},
function(){
    //nothing to reduce
},
{
    out:{inline:true}
});

out:{inline:true} works for small datasets, when result fits into 16Mb limit. For larger responses you need to output to a collection, which you can query and iterate as usual.