【问题标题】:Conversion from String to MongoDB ObjectID从 String 到 MongoDB ObjectID 的转换
【发布时间】:2015-04-10 05:09:54
【问题描述】:

我尝试将我的 String ID 转换为 MongoDB ObjectID

public class relevancy_test extends  Object implements Comparable<ObjectId> {
    public static void main(String[] args) throws UnknownHostException {
        MongoClient mongo = new MongoClient("localhost", 27017);
        DB mydb = mongo.getDB("test");
        DBCollection mycoll = mydb.getCollection("mytempcoll");
        BasicDBObject query = null;
        Map<ObjectId, DBObject> updateMap = new HashMap<ObjectId, DBObject>();
        List<DBObject> dbobj = null;
        DBCursor cursor = mycoll.find();
        dbobj = cursor.toArray();

        for (DBObject postObj : dbobj) {
            String id = postObj.get("_id").toString();
            ObjectId objId = new ObjectId((String) postObj.get("_id"));
            updateMap.put(objId, postObj);
        }
    }
}

这里(String) postObj.get("_id") 的格式为"8001_469437317594492928_1400737805000"

运行时出现以下错误

Exception in thread "main" java.lang.IllegalArgumentException: invalid ObjectId [8001_469437317594492928_1400737805000]
    at org.bson.types.ObjectId.<init>(ObjectId.java:181)
    at org.bson.types.ObjectId.<init>(ObjectId.java:167)
    at fetch_data_tanmay.relevancy_test.main(relevancy_test.java:48)

【问题讨论】:

    标签: java mongodb mongodb-java


    【解决方案1】:

    我看到这里有两个问题:

    1. 如何获取 ObjectID 实例的正确 id?

    8001_469437317594492928_1400737805000 不是您可以在数据库中看到的十六进制值,而是时间、机器 ID、pid 和计数器组件的显式串联。该组件用于生成 HEX 值。要获得 HEX 值,您需要使用 ObjectID 实例的 ToString 方法。

    这里参考ObjectID组件的解释: https://api.mongodb.com/java/3.0/org/bson/types/ObjectId.html

    1. 如何创建具有特定 Id 的 ObjectId 实例

    为了创建具有特定 HEX 值的新 ObjectID 实例,请使用以下命令: var objectId = new ObjectId(hexStringId)

    【讨论】:

    • 第二种解决方案对我有用。实际上在我的 Java Spring MVC 中,这条语句写成 ObjectId OfflineModId = new ObjectId("");
    【解决方案2】:

    这是一个可以为您服务的示例:

    public List<Persona> findAlls() {
            List<Persona> personas = new ArrayList();
            MongoCollection<BasicDBObject> collection = baseDato.database.getCollection("persona", BasicDBObject.class);
            try (MongoCursor<BasicDBObject> cursor = collection.find().iterator()) {
                while (cursor.hasNext()) {
    
                    BasicDBObject theObj = cursor.next();
    
                    String _id = ((ObjectId) theObj.get("_id")).toHexString();
                    String nombre = (String) theObj.get("nombre");
                    String apellido = (String) theObj.get("apellido");
                    String usuario = (String) theObj.get("usuario");
                    String contrasenna = (String) theObj.get("contrasenna");
    
                    Persona persona = new Persona();
                    persona.setNombre(nombre);
                    persona.setApellido(apellido);
                    persona.setUsuario(usuario);
                    persona.setContrasenna(contrasenna);
    
                    personas.add(persona);
    
                }
            }
            return personas;
        }
    

    【讨论】:

      【解决方案3】:

      ObjectId 是一个 12 字节的 BSON 类型

      您的字符串“8001_469437317594492928_1400737805000”不是 12 字节 BSON 类型。所以根据ObjectId更新

      使用具有唯一十六进制字符串的 ObjectId() 构造函数生成新的 ObjectId:

      var stringObjectId = ObjectId("507f191e810c19729de860ea");
      

      请使字符串正确以将字符串转换为 objectId。

      【讨论】:

      【解决方案4】:

      从 List 中检索时,将其直接转换为 ObjectId

       for (DBObject postObj : dbobj) {
              ObjectId objId = (ObjectId)postObj.get("_id");
              updateMap.put(objId, postObj);
      }
      

      【讨论】:

        【解决方案5】:

        我可以将 String 转换为 ObjectId,如下所示:

        这里我正在更新“地址”集合的邮政编码,假设您将得到 REST api 输入,如下所示:

        {  
           "id": "5b38a95eb96e09a310a21778",
           "zip":"10012"
        }
        

        现在我必须根据上面提到的 id(在 mongodb 中是一个 ObjectId)来查找地址记录。为此,我有一个 mongorepository,并使用以下代码查找地址记录:

        @Repository
        public interface AddressRepository extends MongoRepository<Address, String>{
        
        @Query("{'_id': ?0}")
        Address findByObjectId(ObjectId id);
        
        }
        

        并在您的服务类中使用此存储库方法,例如:

            public void updateZipCode(Address addressInput){
                Address address = 
        addressRepository.findByObjectId(new ObjectId(addressInput.getId()));
                //here you will get address record based on the id
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-12-30
          • 1970-01-01
          • 2020-09-09
          • 1970-01-01
          • 1970-01-01
          • 2017-08-29
          • 1970-01-01
          • 2021-05-05
          相关资源
          最近更新 更多