使用 MongoDb 创建索引

Posted

技术标签:

【中文标题】使用 MongoDb 创建索引【英文标题】:Create an index with MongoDb 【发布时间】:2012-12-09 23:41:47 【问题描述】:

我是 MongoDB 的初学者,我正在尝试一些东西。 我想存储 URL 并避免重复的 URL,我在 url 上创建了一个唯一索引。 就这样

collection.createIndex(new BasicDBObject("url", type).append("unique", true));

但是每次我启动我的程序时,索引都会再次创建,不是吗?

因为,现在我的程序只插入一个网址“http://site.com”,如果我重新启动我的程序,这个网址会再次插入,就像没有索引一样。

每次都创建索引是处理索引的错误方式吗?

这是我的代码示例

mongo.getCollection().ensureIndex(new BasicDBObject("url", 1).append("unique", "true"));

mongo.getCollection().insert(new BasicDBObject("url", "http://site.com").append("crawled", 0));

mongo.getCollection().insert(new BasicDBObject("url", "http://site.com").append("crawled", 0));

然后输出:

 "_id" :  "$oid" : "50d627cf44ae5d6b5e9cf106" , "url" : "http://site.com" , "crawled" : 0
 "_id" :  "$oid" : "50d627cf44ae5d6b5e9cf107" , "url" : "http://site.com" , "crawled" : 0

谢谢

编辑:

这是我的 Mongo 类,它处理 MongoDB 导入 java.net.UnknownHostException; 导入 java.util.List; 导入 java.util.Set;

导入 com.mongodb.BasicDBObject; 导入com.mongodb.DB; 导入 com.mongodb.DBCollection; 导入 com.mongodb.DBObject; 导入 com.mongodb.MongoClient;

public class Mongo 

    private MongoClient mongoClient;
    private DB db;
    private DBCollection collection;
    private String db_name;

    public Mongo(String db)

        try 
            mongoClient = new MongoClient( "localhost" , 27017 );

            this.db = mongoClient.getDB(db);
            this.db_name = db;
         catch (UnknownHostException e) 
            e.printStackTrace();
        

    

    public void drop()
        mongoClient.dropDatabase(db_name);
    

    public void listCollections()
        Set<String> colls = db.getCollectionNames();

        for (String s : colls) 
            System.out.println(s);
        
    

    public void listIndex()
         List<DBObject> list = collection.getIndexInfo();

            for (DBObject o : list) 
                System.out.println("\t" + o);
            
    

    public void setCollection(String col)
        this.collection = db.getCollection(col);
    

    public void insert(BasicDBObject doc)

        this.collection.insert(doc);

    

    public DBCollection getCollection()
        return collection;
    

    public void createIndex(String on, int type)
        collection.ensureIndex(new BasicDBObject(on, type).append("unique", true));
    



这是处理我的程序的班级

public class Explorer 

    private final static boolean DEBUG = false;
    private final static boolean RESET = false;

    private Mongo mongo;

    private String host;

    public Explorer(String url)
        mongo = new Mongo("explorer");
        mongo.setCollection("page");

        if (RESET)
            mongo.drop();
            System.out.println("Set RESET to FALSE and restart the program.");
            System.exit(1);
        

        if (DEBUG) 
            mongo.listCollections();

        

        this.host = url.toLowerCase();



        BasicDBObject doc = new BasicDBObject("url", "http://site.com").append("crawled", 0);

        mongo.getCollection().ensureIndex(new BasicDBObject("url", 1).append("unique", true));

        mongo.getCollection().insert(new BasicDBObject("url", "http://site.com").append("crawled", 0));

        mongo.getCollection().insert(new BasicDBObject("url", "http://site.com").append("crawled", 0));




        process();
    


    private void process()


        BasicDBObject query = new BasicDBObject("crawled", 0);

        DBCursor cursor = mongo.getCollection().find(query);

        try 
            while(cursor.hasNext()) 
                System.out.println(cursor.next());
            
         finally 
            cursor.close();
        

    

【问题讨论】:

【参考方案1】:

我不完全理解您的问题,但我觉得您很可能应该使用 ensureIndex 而不是 createIndex,因为后者总是尝试创建索引,而前者只会确保 它存在。

【讨论】:

我尝试使用collection.ensureIndex(new BasicDBObject("url", 1).append("unique", true));,但这是同样的问题。实际上我的问题是我在 url 上有一个唯一索引,但是如果我多次插入同一个 url,那么我有很多记录,而不仅仅是一个。【参考方案2】:

您需要将唯一值作为布尔值 true 传递,而不是作为字符串传递,第二个参数是选项:

...ensureIndex(new BasicDBObject("url", 1), new BasicDBObject("unique", true));

另外,我使用 mongo 解释器手动测试了它:

> db.createCollection("sa")
 "ok" : 1 
> db.sa.ensureIndex("url":1,unique:true)
> db.sa.insert(url:"http://www.example.com", crawled: true)
> db.sa.insert(url:"http://www.example.com", crawled: true)
E11000 duplicate key error index: test.sa.$url_1  dup key:  : "http://www.example.com" 
> db.sa.insert(url:"http://www.example2.com/", crawled: false)
> db.sa.insert(url:"http://www.example.com", crawled: false)
E11000 duplicate key error index: test.sa.$url_1  dup key:  : "http://www.example.com" 
>

只有两个对象:

> db.sa.find()
 "_id" : ObjectId("50d636baa050939da1e4c53b"), "url" : "http://www.example.com", "crawled" : true 
 "_id" : ObjectId("50d636dba050939da1e4c53d"), "url" : "http://www.example2.com/", "crawled" : false 

【讨论】:

我已经用 true 作为布尔值进行了测试,但这是同样的问题。 用你当前的代码更新你的问题,它一定很微妙。 是的,也许,我刚刚添加了我的 2 类 您没有按照我的建议更改代码。选项,如 unique 必须作为第二个参数(或第三个)传递:更多信息 ensureIndex 不要使用 .append 作为关键参数的一部分。 哎呀,我没看到区别。现在可以了,谢谢;)【参考方案3】:

要使用 mongodb 的唯一索引,您应该使用带有 2 个参数的方法,其中第三个布尔参数用于“唯一”索引。

mongo.getCollection().ensureIndex(new BasicDBObject("url", 1),"unq_url", true));

【讨论】:

【参考方案4】:

我还看到您没有在 getCollection(); 中指定集合名称

那会选择什么系列?好奇

【讨论】:

NM,我看到你使用 setCollection() 抱歉【参考方案5】:

刚刚偶然发现这个问题,自 3.0.0 版以来有一些变化

db.collection.ensureIndex(keys, options)

自 3.0.0 版起已弃用:db.collection.ensureIndex() 现在是 db.collection.createIndex() 的别名。

如果索引尚未创建,则在指定字段上创建索引 存在。

【讨论】:

以上是关于使用 MongoDb 创建索引的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 创建基础索引组合索引唯一索引以及优化

MongoDB 创建基础索引组合索引唯一索引以及优化

MongoDB 创建基础索引组合索引唯一索引以及优化

Ruby操作MongoDB(进阶六)-索引Indexing

MongoDB中索引的创建和使用详解

MongoDB - 如何提高创建索引的性能?