Создайте индекс с помощью MongoDb
Я начинаю с MongoDB, и я пытаюсь кое-что изложить.
Я хочу сохранить URL-адрес и избежать дублирования URL-адреса. Я создаю уникальный индекс в URL-адресе.
Подобно этому
collection.createIndex(new BasicDBObject("url", type).append("unique", true));
Но каждый раз, когда я запускаю свою программу, индекс снова создается, не так ли?
Потому что теперь моя программа только вставляет один URL-адрес "http://site.com", и если я перезапущу свою программу, этот URL-адрес снова вставлен, как если бы не был индекс.
Создание индекса каждый раз является неправильным способом обработки индекса?
Вот пример моего кода
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
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));
}
}
И вот мой класс, который обрабатывает мою программу
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
Вам нужно будет передать уникальное значение в качестве логического значения 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 }
Ответ 2
Я не совсем понимаю вашу проблему, но я считаю очень вероятным использовать ensureIndex
вместо createIndex
, поскольку последний всегда пытается создать индекс, а первый будет только гарантировать, что он существует.
Ответ 3
Просто наткнулся на этот вопрос, и с версии 3.0.0 произошли некоторые изменения.
db.collection.ensureIndex(keys, options)
Устаревший с версии 3.0.0: db.collection.ensureIndex() теперь является псевдоним для db.collection.createIndex().
Создает индекс в указанном поле, если индекс еще не установлен существуют.
Ответ 4
Чтобы использовать уникальный индекс mongodb, вы должны использовать метод с двумя параметрами, где третий булевский параметр предназначен для "уникального" индекса.
mongo.getCollection(). makeIndex (новый BasicDBObject ( "url", 1), "unq_url", true));
Ответ 5
Также я вижу, что у вас нет имени коллекции, указанного в getCollection();
Какую сборку выберете? Любопытно
Ответ 6
Ответ немного поздно, но если кому-то нужен более простой способ создания индекса: https://studio3t.com/whats-new/adding-modifying-mongodb-indexes/