Mongodb cursor.toArray()太慢了

时间:2018-05-09 00:02:22

标签: mongodb mongojack

我使用cursor.toArray()collection.find(query)作为列表返回,我的API的响应时间为100毫秒。获取到光标的数据非常少(几百条记录),数据库在我查询的字段上编入索引。我还设置了批量大小cursor.batchSize(1000)

db.collection.find({"{ "ZIP" : { "$in" : [ "12345"]}}"})是我的查询,我的数据库被编入“ZIP”索引。我可以在4毫秒内看到在shell上运行相同的查询。

mongo shell上的相同查询几乎不需要5毫秒。

我使用的Mogo司机是:

<!-- https://mvnrepository.com/artifact/org.mongojack/mongojack -->
<dependency>
    <groupId>org.mongojack</groupId>
    <artifactId>mongojack</artifactId>
    <version>2.8.2</version>
</dependency>

代码

@Path("/")
@Produces(MediaType.APPLICATION_JSON)
@Api(value = "listing-mongo")
public class MlsMongoResource {

    private JacksonDBCollection<Mlsdatadao, String> collection;
    Clock clock;

    public MlsMongoResource(JacksonDBCollection<Mlsdatadao, String> collection) {
        this.collection = collection;
        this.clock =  Clock.systemUTC();
    }

    @GET
    @Path("/listings-mongo")
    @Produces(value = MediaType.APPLICATION_JSON)
    @Timed
    public List<Mlsdatadao> getListings(@BeanParam MlsListingParameters mlsBeanParam) {

        BasicDBList basicDbList = new BasicDBList();
        mlsBeanParam.validateBean();

        setLocations(basicDbList,mlsBeanParam.zipcodes);

        BasicDBObject query = new BasicDBObject("$and", basicDbList);

        DBCursor<Mlsdatadao> cursor = null;

        long start = 0;
        try{
             start = System.currentTimeMillis();
            cursor = collection.find(query);
            cursor.batchSize(1000);

        } catch (Exception e){
            System.out.println("IN collection.find() " +  e.getCause());
        }


        System.out.println("QUERY LIST IS " + basicDbList);

        if(cursor == null) {
            System.out.println("Cursor is null");
        }
        List<Mlsdatadao> result = cursor.toArray();
       cursor.close();(System.currentTimeMillis() - start));
        return result;

    }



    private void setLocations(BasicDBList basicDbList, List<String> zipcodes) {

        if (CollectionUtils.isNotEmpty(zipcodes)) {
            basicDbList.add(setZipcodes(zipcodes));
        }

    }

    private BasicDBObject setZipcodes(List<String> zipcodes) {
        return new BasicDBObject("ZIP" ,  new BasicDBObject("$in", zipcodes) );
    }
}

应用:

public class MongoApplication extends Application <MlsMongoConfiguration> {

    public static void main(String[] args) throws Exception {
        new MlsMongoApplication().run(args);
    }

    @Override
    public String getName() {
        return "mls-dropwizard-mongo";
    }

    @Override
    public void initialize(Bootstrap<MlsMongoConfiguration> bootstrap) {

        bootstrap.addBundle(new SwaggerBundle<MlsMongoConfiguration>() {
            @Override
            protected SwaggerBundleConfiguration getSwaggerBundleConfiguration(MlsMongoConfiguration configuration) {
                return configuration.swaggerBundleConfiguration;
            }
        });

    }

    @Override
    public void run(MlsMongoConfiguration configuration, Environment environment) throws Exception {


        MongoClientOptions.Builder clientOptions = new MongoClientOptions.Builder();
        clientOptions.minConnectionsPerHost(1000);//min
        clientOptions.maxWaitTime(1000);
        clientOptions.connectionsPerHost(1000);

        //Create Mongo instance
        //Mongo mongo = new Mongo(configuration.mongohost, configuration.mongoport);

        MongoClient mongoClient = new MongoClient(new ServerAddress(configuration.mongohost, configuration.mongoport), clientOptions.build());

        //Add Managed for managing the Mongo instance
        //MongoManaged mongoManaged = new MongoManaged(mongo);
        MongoManaged mongoManaged = new MongoManaged(mongoClient);
        environment.lifecycle().manage(mongoManaged);

        //Add Health check for Mongo instance. This will be used from the Health check admin page
        environment.healthChecks().register("MongoHealthCheck", new MongoHealthCheck(mongoClient));
        //Create DB instance and wrap it in a Jackson DB collection
        DB db = mongoClient.getDB(configuration.mongodb);
        JacksonDBCollection<Mlsdatadao, String> jacksonDBCollection = JacksonDBCollection.wrap(db.getCollection("mlsdata"), Mlsdatadao.class, String.class);
        environment.jersey().register(new MlsMongoResource(jacksonDBCollection));
    }
}

有没有办法避免cursor.toArray()?任何其他性能调整提示都会非常有用。

感谢。

1 个答案:

答案 0 :(得分:0)

将MongoDB驱动程序从mongojack更改为原生mongo-java-driver 3.7并使用com.mongodb.client.FindIterable而不是DBCursor后,情况看起来不错。看起来Mongojack库花了很多时间将BSON对象映射到POJO。