2012-06-18 28 views
7

Tôi đang sử dụng java/morphia để đối phó với mongodb. ObjectId mặc định không phải là rất thuận tiện để sử dụng từ lớp Java. Tôi muốn làm cho nó một loại String trong khi giữ cho quá trình tạo khóa bằng cách sử dụng ObjectId, nói _id = new ObjectId.toString().Tôi có thể sử dụng String làm loại ID cho tài liệu mongodb không?

Tôi muốn biết liệu có tác dụng phụ nào xảy ra theo cách này không? Ví dụ, nó sẽ tác động đến hiệu suất cơ sở dữ liệu hoặc gây xung đột quan trọng trong bất kỳ phương tiện nào? Nó có ảnh hưởng đến môi trường sharding ...

+0

Bạn có thể giải thích thêm về lý do ObjectId bất tiện không? Bạn có thể dễ dàng tạo lại một từ một chuỗi như 'id = new ObjectId (str)' –

+0

String là kiểu được sử dụng trong mọi chương trình Java, trong khi ObjectId thì không. Tôi không muốn giới thiệu một loại mới cho các thành phần khác sử dụng thư viện của tôi. có lẽ nó sẽ yêu cầu morphia, mongodb và thư viện bson được nhập khẩu, nó vẫn tốt hơn nếu mọi người sử dụng thư viện của tôi là trong suốt đối với các loại mongodb bao gồm ObjectId –

+0

Hmm ... nhưng nếu thư viện của bạn đang lưu trữ dữ liệu trong Mongo, sẽ không mongo.jar cần phải được trong classpath anyway? Ngoài ra, có một tạo trên không và thu gom rác rất nhiều Strings. –

Trả lời

18

Bạn có thể sử dụng bất kỳ loại giá trị nào cho trường _id (ngoại trừ Mảng). Nếu bạn chọn không sử dụng ObjectId, bạn sẽ phải bằng cách nào đó đảm bảo tính duy nhất của các giá trị (đúc ObjectId thành chuỗi sẽ làm). Nếu bạn cố gắng chèn khóa trùng lặp, lỗi sẽ xảy ra và bạn sẽ phải đối phó với nó.

Tôi không chắc chắn nó sẽ ảnh hưởng đến cụm sao khi bạn cố gắng chèn hai tài liệu với cùng một _id vào các phân đoạn khác nhau. Tôi nghi ngờ rằng nó sẽ cho phép bạn chèn, nhưng điều này sẽ cắn bạn sau này. (Tôi sẽ phải kiểm tra điều này).

Điều đó nói rằng, bạn sẽ không gặp khó khăn nào với _id = (new ObjectId).toString().

+0

Tốt. cảm ơn! –

+0

Câu thứ hai và thứ ba của bạn chống lại nhau. Thứ ba là chính xác. Đừng nghi ngờ trong câu trả lời. Ngoài ra, '_id' có thể giữ giá trị kiểu 'mảng'. – Dyin

+0

Làm thế nào chính xác là họ mâu thuẫn với nhau? –

4

Tôi thực sự đã làm điều tương tự vì tôi đã gặp một số vấn đề khi chuyển đổi ObjectId thành JSON.

sau đó tôi đã làm một cái gì đó giống như

@Id 
private String id; 
public String getId() { 
    return id(); 
} 
public void setId(String id) { 
    this.id = id; 
} 

Và tất cả mọi thứ đã làm việc tốt cho đến khi tôi quyết định để cập nhật một tài liệu chèn trước đây, khi tôi đã nhận đối tượng bằng cách Id gửi nó tới trang thông qua JSON và nhận các đối tượng được cập nhật cùng cũng bằng bài đăng JSON và sau đó sử dụng chức năng lưu từ Datastore, thay vì cập nhật dữ liệu trước đó, nó chèn một tài liệu mới thay vì cập nhật tài liệu đã có.

Thậm chí tệ nhất là tài liệu mới có cùng ID so với tài liệu được chèn trước đó, điều tôi nghĩ là không thể.

Dù sao tôi đã định vị đối tượng riêng tư thành một ObjectID và chỉ để lại tập hợp làm chuỗi và sau đó nó hoạt động như mong đợi, không chắc chắn giúp ích trong trường hợp của bạn.

@Id 
private ObjectId id; 
public String getId() { 
    return id.toString(); 
} 
public void setId(String id) { 
    this.id = new ObjectId(id); 
} 
1

Có, bạn có thể sử dụng chuỗi làm _id của mình.

Tôi muốn giới thiệu nó chỉ khi bạn có một số giá trị (trong tài liệu) tự nhiên là một khóa duy nhất tốt. Tôi đã sử dụng thiết kế này trong một bộ sưu tập có một thẻ địa lý chuỗi, có dạng "xxxxyyyy"; trường duy nhất cho mỗi tài liệu này sẽ CÓ trong tài liệu Tôi phải xây dựng một chỉ mục trên đó ... vậy tại sao không sử dụng nó làm khóa? (Điều này tránh được một cặp khóa-giá trị bổ sung, VÀ tránh chỉ mục thứ hai trên bộ sưu tập, vì MondoDB tự nhiên xây dựng chỉ mục trên "_id". Cho kích thước của bộ sưu tập, cả hai bộ nhớ này được thêm vào một số khoản tiết kiệm không gian nghiêm trọng.)

Tuy nhiên, từ giai điệu của câu hỏi của bạn ("ObjectID không thuận tiện"), nếu lý do duy nhất bạn muốn sử dụng chuỗi là bạn không muốn bị làm phiền với việc tìm hiểu cách quản lý gọn gàng ObjectID .. Tôi đề nghị bạn nên dành thời gian để có được đầu xung quanh họ. Tôi chắc chắn rằng họ không gặp rắc rối ... một khi bạn đã tìm ra rắc rối của bạn với họ.

Nếu không: tùy chọn của bạn là gì? Bạn sẽ kết hợp các chuỗi chuỗi MỌI THỜI GIAN bạn sử dụng MongoDB trong tương lai?

+1

Xin cảm ơn vì đã quay lại câu hỏi của tôi gần bốn năm trước. Tôi nghĩ rằng tôi đã có thêm sự hiểu biết về MongoDB kể từ đó. Và bây giờ tôi xem xét việc lưu trữ ObjectId như một chuỗi thực sự là một ý tưởng tồi, bởi vì ObjectId có nghĩa là ba số nguyên trong khi biểu diễn chuỗi của nó là 24 ký tự, không hiệu quả cả về không gian và thời gian. –

1

Tôi muốn thêm rằng không phải lúc nào cũng nên sử dụng BSON ObjectID được tạo tự động làm mã định danh duy nhất, nếu nó được chuyển đến ứng dụng: nó có khả năng bị người dùng thao tác. Các ObjectID dường như được tạo tuần tự, vì vậy nếu bạn không triển khai các cơ chế ủy quyền cần thiết, người dùng độc hại có thể tăng giá trị mà anh ta có, để truy cập các tài nguyên mà anh ta không có quyền truy cập.

Do đó, việc sử dụng mã định danh loại UUID sẽ cung cấp một lớp bảo mật tối thiểu. Tất nhiên, Ủy quyền (là người dùng này được phép truy cập tài nguyên được yêu cầu) là phải, nhưng bạn nên biết tính năng ObjectID nói trên.

Để tận dụng tối đa cả hai thế giới, hãy tạo UUID khớp với chiều dài ObjectID của bạn (12 hoặc 24 ký tự) và sử dụng nó để tạo _id loại ObjectID của riêng bạn.

+2

"nếu bạn không triển khai ủy quyền cần thiết", bạn vẫn phải chịu số phận. Sự tối tăm không phải là an ninh. Nó chỉ lừa mình "chúng ta an toàn". – Piohen

+0

@Piohen làm thế nào mọi người không đọc đoạn thứ hai là vượt ra ngoài tôi ... –

Các vấn đề liên quan