Je suis débutant avec MongoDB et je suis en train d'essayer quelques trucs. Je veux stocker une URL et éviter les URL en double, je crée un index unique sur l'URL. Comme ça
collection.createIndex(new BasicDBObject("url", type).append("unique", true));
Mais chaque fois que je lance mon programme, l'index est créé à nouveau, n'est-ce pas?
Parce que, maintenant, mon programme n’insère plus qu’une seule URL "http://site.com" et si je relance mon programme, cette URL est de nouveau insérée, comme s’il n’y avait pas d’index.
Créer l'index à chaque fois est la mauvaise façon de gérer un index?
Voici un exemple de mon code
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));
Et la sortie:
{ "_id" : { "$oid" : "50d627cf44ae5d6b5e9cf106"} , "url" : "http://site.com" , "crawled" : 0}
{ "_id" : { "$oid" : "50d627cf44ae5d6b5e9cf107"} , "url" : "http://site.com" , "crawled" : 0}
Merci
MODIFIER :
Voici ma classe Mongo qui gère MongoDB Import Java.net.UnknownHostException; Import Java.util.List; Import Java.util.Set;
import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBObject; import 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));
}
}
Et voici ma classe qui gère mon programme
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();
}
}
}
Vous devrez passer la valeur unique en tant que valeur booléenne true et non en tant que chaîne. Ce sont les deuxièmes paramètres qui sont des options:
...ensureIndex(new BasicDBObject("url", 1), new BasicDBObject("unique", true));
De plus, je l'ai testé manuellement en utilisant l'interpréteur 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" }
>
Il n'y a que les deux objets:
> db.sa.find()
{ "_id" : ObjectId("50d636baa050939da1e4c53b"), "url" : "http://www.example.com", "crawled" : true }
{ "_id" : ObjectId("50d636dba050939da1e4c53d"), "url" : "http://www.example2.com/", "crawled" : false }
Je suis tombé par hasard sur cette question et il y a quelques changements depuis la version 3.0.0
db.collection.ensureIndex(keys, options)
Déconseillé depuis la version 3.0.0: db.collection.ensureIndex () est désormais un alias Pour db.collection.createIndex ().
Crée un index sur le champ spécifié s'il n'existe pas encore .
Je ne comprends pas tout à fait votre problème, mais j'estime qu'il est très probable que vous devriez utiliser ensureIndex
au lieu de createIndex
car ce dernier tente toujours de créer l'index, tandis que le premier ne fera que garantira qu'il existe.
De plus, je constate que vous n'avez pas de nom de collection spécifié dans getCollection ();
Quelle collection cela sélectionnerait-il? curieuse
Pour utiliser l'index unique de mongodb, vous devez utiliser la méthode avec 2 paramètres, le 3ème paramètre booléen correspondant à l'index "unique".
mongo.getCollection (). EnsureIndex (new BasicDBObject ("url", 1), "unq_url", true));