Tham chiếu tài liệu mongodb

Khung ánh xạ không phải lưu trữ các đối tượng con được nhúng trong tài liệu. Bạn cũng có thể lưu trữ chúng riêng biệt và sử dụng

Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
5 để tham khảo tài liệu đó. Khi đối tượng được tải từ MongoDB, các tham chiếu đó sẽ được giải quyết một cách háo hức để bạn lấy lại một đối tượng được ánh xạ trông giống như thể nó đã được lưu trữ nhúng trong tài liệu cấp cao nhất của bạn

Ví dụ sau đây sử dụng DBRef để tham chiếu đến một tài liệu cụ thể tồn tại độc lập với đối tượng mà nó được tham chiếu (cả hai lớp được hiển thị trong dòng vì lý do ngắn gọn)

@Document
public class Account {

  @Id
  private ObjectId id;
  private Float total;
}

@Document
public class Person {

  @Id
  private ObjectId id;
  @Indexed
  private Integer ssn;
  @DBRef
  private List<Account> accounts;
}

Bạn không cần sử dụng

Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
6 hoặc các cơ chế tương tự vì Danh sách các đối tượng cho khung ánh xạ biết rằng bạn muốn có mối quan hệ một-nhiều. Khi đối tượng được lưu trữ trong MongoDB, sẽ có một danh sách các DBRef thay vì chính các đối tượng
Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
7. Khi nói đến việc tải các bộ sưu tập của
Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
5, nên hạn chế các tham chiếu được giữ trong các loại bộ sưu tập đối với một bộ sưu tập MongoDB cụ thể. Điều này cho phép tải hàng loạt tất cả các tham chiếu, trong khi các tham chiếu trỏ đến các bộ sưu tập MongoDB khác nhau cần được giải quyết từng cái một

Quan trọng

Khung ánh xạ không xử lý lưu theo tầng. Nếu bạn thay đổi một đối tượng
Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
7 được tham chiếu bởi một đối tượng
{
  "_id" : …,
  "accounts" : [ "6509b9e" ]                        (4)
}
0, bạn phải lưu riêng đối tượng
Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
7. Việc gọi
{
  "_id" : …,
  "accounts" : [ "6509b9e" ]                        (4)
}
2 trên đối tượng
{
  "_id" : …,
  "accounts" : [ "6509b9e" ]                        (4)
}
0 không tự động lưu các đối tượng
Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
7 trong thuộc tính
{
  "_id" : …,
  "accounts" : [ "6509b9e" ]                        (4)
}
5

Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
5s cũng có thể được giải quyết một cách lười biếng. Trong trường hợp này,
{
  "_id" : …,
  "accounts" : [ "6509b9e" ]                        (4)
}
7 hoặc
{
  "_id" : …,
  "accounts" : [ "6509b9e" ]                        (4)
}
8 thực tế của tham chiếu được giải quyết trong lần truy cập đầu tiên vào thuộc tính. Sử dụng thuộc tính
{
  "_id" : …,
  "accounts" : [ "6509b9e" ]                        (4)
}
9 của
@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                            (1)
  String name;

  @DocumentReference(lazy = true)                            (2)
  List<Book> books;

}
0 để chỉ định điều này. Các thuộc tính bắt buộc cũng được định nghĩa là lazy loading
Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
5 và được sử dụng làm đối số hàm tạo cũng được trang trí bằng proxy lazy loading để đảm bảo gây ít áp lực nhất có thể lên cơ sở dữ liệu và mạng

Mẹo

Có thể khó gỡ lỗi các
Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
5 được tải chậm. Đảm bảo rằng công cụ không vô tình kích hoạt độ phân giải proxy bởi e. g. gọi
@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                            (1)
  String name;

  @DocumentReference(lazy = true)                            (2)
  List<Book> books;

}
3 hoặc một số hiển thị gỡ lỗi nội tuyến gọi trình nhận thuộc tính. Vui lòng cân nhắc bật ghi nhật ký theo dõi cho
@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                            (1)
  String name;

  @DocumentReference(lazy = true)                            (2)
  List<Book> books;

}
4 để hiểu rõ hơn về giải pháp
Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
5

thận trọng

Tải chậm có thể yêu cầu proxy lớp, do đó, có thể cần quyền truy cập vào nội bộ jdk, không mở, bắt đầu với Java 16+, do JEP 396. Đóng gói mạnh mẽ nội bộ JDK theo mặc định. Đối với những trường hợp đó, vui lòng xem xét quay lại loại giao diện (ví dụ:. chuyển từ
@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                            (1)
  String name;

  @DocumentReference(lazy = true)                            (2)
  List<Book> books;

}
6 sang
@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                            (1)
  String name;

  @DocumentReference(lazy = true)                            (2)
  List<Book> books;

}
7) hoặc cung cấp đối số
@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                            (1)
  String name;

  @DocumentReference(lazy = true)                            (2)
  List<Book> books;

}
8 bắt buộc

Sử dụng tài liệu tham khảo

Sử dụng

@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                            (1)
  String name;

  @DocumentReference(lazy = true)                            (2)
  List<Book> books;

}
9 cung cấp một cách linh hoạt để tham chiếu các thực thể trong MongoDB. Mặc dù mục tiêu giống như khi sử dụng , nhưng biểu diễn cửa hàng thì khác.
Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
5 phân giải thành tài liệu có cấu trúc cố định như được nêu trong tài liệu tham khảo MongoDB
Tài liệu tham khảo, không theo một định dạng cụ thể. Chúng có thể là bất cứ thứ gì theo đúng nghĩa đen, một giá trị đơn lẻ, toàn bộ tài liệu, về cơ bản là mọi thứ có thể được lưu trữ trong MongoDB. Theo mặc định, lớp ánh xạ sẽ sử dụng giá trị id của thực thể được tham chiếu để lưu trữ và truy xuất, như trong mẫu bên dưới

@Document
class Account {

  @Id
  String id;
  Float total;
}

@Document
class Person {

  @Id
  String id;

  @DocumentReference                                   (1)
  List<Account> accounts;
}

Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();

{
  "_id" : …,
  "accounts" : [ "6509b9e" ]                        (4)
}

  1. Đánh dấu tập hợp các giá trị

    Account account = …
    
    tempate.insert(account);                               (2)
    
    template.update(Person.class)
      .matching(where("id").is(…))
      .apply(new Update().push("accounts").value(account)) (3)
      .first();
    7 sẽ được tham chiếu

  2. Khung ánh xạ không xử lý lưu theo tầng, vì vậy hãy đảm bảo duy trì từng thực thể được tham chiếu

  3. Thêm tham chiếu đến thực thể hiện có

  4. Các thực thể

    Account account = …
    
    tempate.insert(account);                               (2)
    
    template.update(Person.class)
      .matching(where("id").is(…))
      .apply(new Update().push("accounts").value(account)) (3)
      .first();
    7 được tham chiếu được biểu diễn dưới dạng một mảng gồm các giá trị
    {
      "_id" : 9a48e32,
      "title" : "The Warded Man",
      "author" : ["Peter V. Brett"],
      "publisher_ac" : "DR"
    }
    3 của chúng

Mẫu ở trên sử dụng truy vấn tìm nạp dựa trên

{
  "_id" : 9a48e32,
  "title" : "The Warded Man",
  "author" : ["Peter V. Brett"],
  "publisher_ac" : "DR"
}
3 (
{
  "_id" : 9a48e32,
  "title" : "The Warded Man",
  "author" : ["Peter V. Brett"],
  "publisher_ac" : "DR"
}
5) để truy xuất dữ liệu và giải quyết các thực thể được liên kết một cách háo hức. Có thể thay đổi mặc định độ phân giải (được liệt kê bên dưới) bằng cách sử dụng các thuộc tính của
@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                            (1)
  String name;

  @DocumentReference(lazy = true)                            (2)
  List<Book> books;

}
9

Bảng 1. @DocumentReference defaultsAttributeDescriptionDefault

{
  "_id" : 9a48e32,
  "title" : "The Warded Man",
  "author" : ["Peter V. Brett"],
  "publisher_ac" : "DR"
}
7

Tên cơ sở dữ liệu đích để tra cứu bộ sưu tập

{
  "_id" : 9a48e32,
  "title" : "The Warded Man",
  "author" : ["Peter V. Brett"],
  "publisher_ac" : "DR"
}
8

{
  "_id" : 9a48e32,
  "title" : "The Warded Man",
  "author" : ["Peter V. Brett"],
  "publisher_ac" : "DR"
}
9

Tên bộ sưu tập mục tiêu

Loại miền của thuộc tính được chú thích, tương ứng là loại giá trị trong trường hợp thuộc tính

{
  "_id" : …,
  "accounts" : [ "6509b9e" ]                        (4)
}
8 like hoặc
{
  "_id" : 1a23e45,
  "acronym" : "DR",
  "name" : "Del Rey",
  
}
1, tên bộ sưu tập

{
  "_id" : 1a23e45,
  "acronym" : "DR",
  "name" : "Del Rey",
  
}
2

Truy vấn tra cứu tài liệu duy nhất đánh giá các trình giữ chỗ thông qua các biểu thức SpEL bằng cách sử dụng

{
  "_id" : 1a23e45,
  "acronym" : "DR",
  "name" : "Del Rey",
  
}
3 làm điểm đánh dấu cho một giá trị nguồn đã cho. Các thuộc tính
{
  "_id" : …,
  "accounts" : [ "6509b9e" ]                        (4)
}
8 like hoặc
{
  "_id" : 1a23e45,
  "acronym" : "DR",
  "name" : "Del Rey",
  
}
1 kết hợp các tra cứu riêng lẻ thông qua toán tử
{
  "_id" : 1a23e45,
  "acronym" : "DR",
  "name" : "Del Rey",
  
}
6

Truy vấn dựa trên trường

{
  "_id" : 9a48e32,
  "title" : "The Warded Man",
  "author" : ["Peter V. Brett"],
  "publisher_ac" : "DR"
}
3 (_______32_______5) sử dụng giá trị nguồn đã tải

{
  "_id" : 1a23e45,
  "acronym" : "DR",
  "name" : "Del Rey",
  
}
9

Được sử dụng để phân loại tài liệu kết quả ở phía máy chủ

Không theo mặc định. Thứ tự kết quả của

{
  "_id" : …,
  "accounts" : [ "6509b9e" ]                        (4)
}
8 thuộc tính tương tự được khôi phục dựa trên truy vấn tra cứu đã sử dụng trên cơ sở nỗ lực tối đa

{
  "_id" : …,
  "accounts" : [ "6509b9e" ]                        (4)
}
9

Nếu được đặt thành

@WritingConverter
class PublisherReferenceConverter implements Converter<Publisher, DocumentPointer<String>> {

	@Override
	public DocumentPointer<String> convert(Publisher source) {
		return () -> source.getAcronym();
	}
}
2, việc giải quyết giá trị bị trì hoãn khi truy cập thuộc tính lần đầu

Giải quyết các thuộc tính một cách háo hức theo mặc định

thận trọng

Tải chậm có thể yêu cầu proxy lớp, do đó, có thể cần quyền truy cập vào nội bộ jdk, không mở, bắt đầu với Java 16+, do JEP 396. Đóng gói mạnh mẽ nội bộ JDK theo mặc định. Đối với những trường hợp đó, vui lòng xem xét quay lại loại giao diện (ví dụ:. chuyển từ
@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                            (1)
  String name;

  @DocumentReference(lazy = true)                            (2)
  List<Book> books;

}
6 sang
@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                            (1)
  String name;

  @DocumentReference(lazy = true)                            (2)
  List<Book> books;

}
7) hoặc cung cấp đối số
@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                            (1)
  String name;

  @DocumentReference(lazy = true)                            (2)
  List<Book> books;

}
8 bắt buộc

@WritingConverter
class PublisherReferenceConverter implements Converter<Publisher, DocumentPointer<String>> {

	@Override
	public DocumentPointer<String> convert(Publisher source) {
		return () -> source.getAcronym();
	}
}
6 cho phép xác định các truy vấn bộ lọc có thể khác với trường
{
  "_id" : 9a48e32,
  "title" : "The Warded Man",
  "author" : ["Peter V. Brett"],
  "publisher_ac" : "DR"
}
3 và do đó cung cấp một cách linh hoạt để xác định các tham chiếu giữa các thực thể như được minh họa trong mẫu bên dưới, trong đó
@WritingConverter
class PublisherReferenceConverter implements Converter<Publisher, DocumentPointer<String>> {

	@Override
	public DocumentPointer<String> convert(Publisher source) {
		return () -> source.getAcronym();
	}
}
8 của một cuốn sách được tham chiếu bằng từ viết tắt của nó thay vì nội bộ
@WritingConverter
class PublisherReferenceConverter implements Converter<Publisher, DocumentPointer<String>> {

	@Override
	public DocumentPointer<String> convert(Publisher source) {
		return () -> source.getAcronym();
	}
}
9

@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                            (1)
  String name;

  @DocumentReference(lazy = true)                            (2)
  List<Book> books;

}

@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @DocumentReference(lookup = "{ 'acronym' : ?#{acc} }") (1) (2)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                        (1)
  String name;

  // ...
}
0 tài liệu

{
  "_id" : 9a48e32,
  "title" : "The Warded Man",
  "author" : ["Peter V. Brett"],
  "publisher_ac" : "DR"
}

Tài liệu

@WritingConverter
class PublisherReferenceConverter implements Converter<Publisher, DocumentPointer<String>> {

	@Override
	public DocumentPointer<String> convert(Publisher source) {
		return () -> source.getAcronym();
	}
}
8

{
  "_id" : 1a23e45,
  "acronym" : "DR",
  "name" : "Del Rey",
  
}

  1. Sử dụng trường

    @Document
    class Book {
    
      @Id
      ObjectId id;
      String title;
      List<String> author;
    
      @DocumentReference(lookup = "{ 'acronym' : ?#{acc} }") (1) (2)
      Publisher publisher;
    }
    
    @Document
    class Publisher {
    
      @Id
      ObjectId id;
      String acronym;                                        (1)
      String name;
    
      // ...
    }
    2 để truy vấn các thực thể trong bộ sưu tập
    @WritingConverter
    class PublisherReferenceConverter implements Converter<Publisher, DocumentPointer<String>> {
    
    	@Override
    	public DocumentPointer<String> convert(Publisher source) {
    		return () -> source.getAcronym();
    	}
    }
    8

  2. Lười tải lại các tham chiếu đến bộ sưu tập

    @Document
    class Book {
    
      @Id
      ObjectId id;
      String title;
      List<String> author;
    
      @DocumentReference(lookup = "{ 'acronym' : ?#{acc} }") (1) (2)
      Publisher publisher;
    }
    
    @Document
    class Publisher {
    
      @Id
      ObjectId id;
      String acronym;                                        (1)
      String name;
    
      // ...
    }
    0

Đoạn mã trên cho thấy khía cạnh đọc của mọi thứ khi làm việc với các đối tượng được tham chiếu tùy chỉnh. Viết yêu cầu một chút thiết lập bổ sung vì thông tin ánh xạ không thể hiện nơi mà

{
  "_id" : 1a23e45,
  "acronym" : "DR",
  "name" : "Del Rey",
  
}
3 bắt nguồn từ. Lớp ánh xạ yêu cầu đăng ký một
@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @DocumentReference(lookup = "{ 'acronym' : ?#{acc} }") (1) (2)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                        (1)
  String name;

  // ...
}
6 giữa tài liệu đích và
@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @DocumentReference(lookup = "{ 'acronym' : ?#{acc} }") (1) (2)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                        (1)
  String name;

  // ...
}
7, giống như bên dưới

@WritingConverter
class PublisherReferenceConverter implements Converter<Publisher, DocumentPointer<String>> {

	@Override
	public DocumentPointer<String> convert(Publisher source) {
		return () -> source.getAcronym();
	}
}

Nếu không cung cấp bộ chuyển đổi

@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @DocumentReference(lookup = "{ 'acronym' : ?#{acc} }") (1) (2)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                        (1)
  String name;

  // ...
}
7, tài liệu tham chiếu đích có thể được tính toán dựa trên truy vấn tra cứu đã cho. Trong trường hợp này, các thuộc tính mục tiêu liên kết được đánh giá như trong mẫu sau

@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @DocumentReference(lookup = "{ 'acronym' : ?#{acc} }") (1) (2)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                        (1)
  String name;

  // ...
}

{
  "_id" : 9a48e32,
  "title" : "The Warded Man",
  "author" : ["Peter V. Brett"],
  "publisher" : {
    "acc" : "DOC"
  }
}

  1. Sử dụng trường

    @Document
    class Book {
    
      @Id
      ObjectId id;
      String title;
      List<String> author;
    
      @DocumentReference(lookup = "{ 'acronym' : ?#{acc} }") (1) (2)
      Publisher publisher;
    }
    
    @Document
    class Publisher {
    
      @Id
      ObjectId id;
      String acronym;                                        (1)
      String name;
    
      // ...
    }
    2 để truy vấn các thực thể trong bộ sưu tập
    @WritingConverter
    class PublisherReferenceConverter implements Converter<Publisher, DocumentPointer<String>> {
    
    	@Override
    	public DocumentPointer<String> convert(Publisher source) {
    		return () -> source.getAcronym();
    	}
    }
    8

  2. Các trình giữ chỗ giá trị trường của truy vấn tra cứu (như

    {
      "_id" : 9a48e32,
      "title" : "The Warded Man",
      "author" : ["Peter V. Brett"],
      "publisher" : {
        "acc" : "DOC"
      }
    }
    1) được sử dụng để tạo thành tài liệu tham khảo

Cũng có thể mô hình hóa các tham chiếu One-To-Many kiểu quan hệ bằng cách sử dụng kết hợp

{
  "_id" : 9a48e32,
  "title" : "The Warded Man",
  "author" : ["Peter V. Brett"],
  "publisher" : {
    "acc" : "DOC"
  }
}
2 và
@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @Field("publisher_ac")
  @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                            (1)
  String name;

  @DocumentReference(lazy = true)                            (2)
  List<Book> books;

}
9. Cách tiếp cận này cho phép các loại liên kết không lưu trữ các giá trị liên kết trong tài liệu sở hữu mà lưu trữ trên tài liệu tham chiếu như trong ví dụ bên dưới

@Document
class Account {

  @Id
  String id;
  Float total;
}

@Document
class Person {

  @Id
  String id;

  @DocumentReference                                   (1)
  List<Account> accounts;
}
0

@Document
class Book {

  @Id
  ObjectId id;
  String title;
  List<String> author;

  @DocumentReference(lookup = "{ 'acronym' : ?#{acc} }") (1) (2)
  Publisher publisher;
}

@Document
class Publisher {

  @Id
  ObjectId id;
  String acronym;                                        (1)
  String name;

  // ...
}
0 tài liệu

@Document
class Account {

  @Id
  String id;
  Float total;
}

@Document
class Person {

  @Id
  String id;

  @DocumentReference                                   (1)
  List<Account> accounts;
}
1

Tài liệu

@WritingConverter
class PublisherReferenceConverter implements Converter<Publisher, DocumentPointer<String>> {

	@Override
	public DocumentPointer<String> convert(Publisher source) {
		return () -> source.getAcronym();
	}
}
8

@Document
class Account {

  @Id
  String id;
  Float total;
}

@Document
class Person {

  @Id
  String id;

  @DocumentReference                                   (1)
  List<Account> accounts;
}
2

  1. Thiết lập liên kết từ

    @Document
    class Book {
    
      @Id
      ObjectId id;
      String title;
      List<String> author;
    
      @DocumentReference(lookup = "{ 'acronym' : ?#{acc} }") (1) (2)
      Publisher publisher;
    }
    
    @Document
    class Publisher {
    
      @Id
      ObjectId id;
      String acronym;                                        (1)
      String name;
    
      // ...
    }
    0 (tham chiếu) đến
    @WritingConverter
    class PublisherReferenceConverter implements Converter<Publisher, DocumentPointer<String>> {
    
    	@Override
    	public DocumentPointer<String> convert(Publisher source) {
    		return () -> source.getAcronym();
    	}
    }
    8 (chủ sở hữu) bằng cách lưu trữ
    {
      "_id" : 9a48e32,
      "title" : "The Warded Man",
      "author" : ["Peter V. Brett"],
      "publisher" : {
        "acc" : "DOC"
      }
    }
    8 trong tài liệu
    @Document
    class Book {
    
      @Id
      ObjectId id;
      String title;
      List<String> author;
    
      @DocumentReference(lookup = "{ 'acronym' : ?#{acc} }") (1) (2)
      Publisher publisher;
    }
    
    @Document
    class Publisher {
    
      @Id
      ObjectId id;
      String acronym;                                        (1)
      String name;
    
      // ...
    }
    0

  2. Đánh dấu thuộc tính giữ các tham chiếu là chỉ đọc. Điều này ngăn việc lưu trữ các tham chiếu đến các

    @Document
    class Book {
    
      @Id
      ObjectId id;
      String title;
      List<String> author;
    
      @DocumentReference(lookup = "{ 'acronym' : ?#{acc} }") (1) (2)
      Publisher publisher;
    }
    
    @Document
    class Publisher {
    
      @Id
      ObjectId id;
      String acronym;                                        (1)
      String name;
    
      // ...
    }
    0 riêng lẻ với tài liệu
    @WritingConverter
    class PublisherReferenceConverter implements Converter<Publisher, DocumentPointer<String>> {
    
    	@Override
    	public DocumentPointer<String> convert(Publisher source) {
    		return () -> source.getAcronym();
    	}
    }
    8

  3. Sử dụng biến

    @Document
    class Account {
    
      @Id
      String id;
      Float total;
    }
    
    @Document
    class Person {
    
      @Id
      String id;
    
      @DocumentReference                                   (1)
      List<Account> accounts;
    }
    02 để truy cập các giá trị trong tài liệu
    @WritingConverter
    class PublisherReferenceConverter implements Converter<Publisher, DocumentPointer<String>> {
    
    	@Override
    	public DocumentPointer<String> convert(Publisher source) {
    		return () -> source.getAcronym();
    	}
    }
    8 và trong tài liệu này truy xuất
    @Document
    class Account {
    
      @Id
      String id;
      Float total;
    }
    
    @Document
    class Person {
    
      @Id
      String id;
    
      @DocumentReference                                   (1)
      List<Account> accounts;
    }
    04 với kết quả khớp với ____27_______05

Với tất cả những điều trên, có thể mô hình hóa tất cả các loại liên kết giữa các thực thể. Hãy xem danh sách mẫu chưa đầy đủ bên dưới để cảm nhận về những gì có thể

ví dụ 1. Tham khảo tài liệu đơn giản sử dụng trường id

@Document
class Account {

  @Id
  String id;
  Float total;
}

@Document
class Person {

  @Id
  String id;

  @DocumentReference                                   (1)
  List<Account> accounts;
}
3

@Document
class Account {

  @Id
  String id;
  Float total;
}

@Document
class Person {

  @Id
  String id;

  @DocumentReference                                   (1)
  List<Account> accounts;
}
4

  1. Loại đơn giản MongoDB có thể được sử dụng trực tiếp mà không cần cấu hình thêm

ví dụ 2. Tham khảo tài liệu đơn giản sử dụng trường id với truy vấn tra cứu rõ ràng

@Document
class Account {

  @Id
  String id;
  Float total;
}

@Document
class Person {

  @Id
  String id;

  @DocumentReference                                   (1)
  List<Account> accounts;
}
5

@Document
class Account {

  @Id
  String id;
  Float total;
}

@Document
class Person {

  @Id
  String id;

  @DocumentReference                                   (1)
  List<Account> accounts;
}
6

  1. đích tự xác định giá trị tham chiếu

ví dụ 3. Tài liệu tham khảo trích xuất trường

@Document
class Account {

  @Id
  String id;
  Float total;
}

@Document
class Person {

  @Id
  String id;

  @DocumentReference                                   (1)
  List<Account> accounts;
}
06 cho truy vấn tra cứu

@Document
class Account {

  @Id
  String id;
  Float total;
}

@Document
class Person {

  @Id
  String id;

  @DocumentReference                                   (1)
  List<Account> accounts;
}
7

@Document
class Account {

  @Id
  String id;
  Float total;
}

@Document
class Person {

  @Id
  String id;

  @DocumentReference                                   (1)
  List<Account> accounts;
}
8

@Document
class Account {

  @Id
  String id;
  Float total;
}

@Document
class Person {

  @Id
  String id;

  @DocumentReference                                   (1)
  List<Account> accounts;
}
9

  1. Khóa được sử dụng để lấy giá trị tham chiếu phải là khóa được sử dụng trong quá trình ghi

  2. @Document
    class Account {
    
      @Id
      String id;
      Float total;
    }
    
    @Document
    class Person {
    
      @Id
      String id;
    
      @DocumentReference                                   (1)
      List<Account> accounts;
    }
    06 là viết tắt của
    @Document
    class Account {
    
      @Id
      String id;
      Float total;
    }
    
    @Document
    class Person {
    
      @Id
      String id;
    
      @DocumentReference                                   (1)
      List<Account> accounts;
    }
    08

Ví dụ 4. Tài liệu tham khảo với nhiều giá trị tạo thành truy vấn tra cứu

Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
0

Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
1

  1. Đọc/ghi các khóa

    @Document
    class Account {
    
      @Id
      String id;
      Float total;
    }
    
    @Document
    class Person {
    
      @Id
      String id;
    
      @DocumentReference                                   (1)
      List<Account> accounts;
    }
    09 &
    @Document
    class Account {
    
      @Id
      String id;
      Float total;
    }
    
    @Document
    class Person {
    
      @Id
      String id;
    
      @DocumentReference                                   (1)
      List<Account> accounts;
    }
    10 từ/đến tài liệu liên kết dựa trên truy vấn tra cứu

  2. Sử dụng các trường không id để tra cứu tài liệu đích

Ví dụ 5. Tài liệu tham khảo đọc từ một bộ sưu tập mục tiêu

Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
2

Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
3

Account account = …

tempate.insert(account);                               (2)

template.update(Person.class)
  .matching(where("id").is(…))
  .apply(new Update().push("accounts").value(account)) (3)
  .first();
4

  1. Đọc/ghi các khóa

    {
      "_id" : 9a48e32,
      "title" : "The Warded Man",
      "author" : ["Peter V. Brett"],
      "publisher_ac" : "DR"
    }
    3 từ/đến tài liệu tham khảo để sử dụng chúng trong truy vấn tra cứu

  2. Tên bộ sưu tập có thể được đọc từ tài liệu tham khảo bằng khóa của nó

Cảnh báo

Chúng tôi biết rằng việc sử dụng tất cả các loại toán tử truy vấn MongoDB trong truy vấn tra cứu là rất hấp dẫn và điều này tốt. Nhưng có một vài khía cạnh để xem xét

  • Đảm bảo có sẵn các chỉ mục hỗ trợ tra cứu của bạn

  • Xin lưu ý rằng độ phân giải yêu cầu độ trễ của máy chủ gây ra độ trễ, hãy xem xét một chiến lược lười biếng

  • Một bộ sưu tập các tham chiếu tài liệu được tải hàng loạt bằng cách sử dụng toán tử

    {
      "_id" : 1a23e45,
      "acronym" : "DR",
      "name" : "Del Rey",
      
    }
    6
    Thứ tự phần tử ban đầu được khôi phục trong bộ nhớ trên cơ sở nỗ lực hết sức. Chỉ có thể khôi phục lại thứ tự khi sử dụng các biểu thức đẳng thức và không thể thực hiện được khi sử dụng các toán tử truy vấn MongoDB. Trong trường hợp này, kết quả sẽ được sắp xếp khi chúng được nhận từ cửa hàng hoặc thông qua thuộc tính
    @Document
    class Account {
    
      @Id
      String id;
      Float total;
    }
    
    @Document
    class Person {
    
      @Id
      String id;
    
      @DocumentReference                                   (1)
      List<Account> accounts;
    }
    13 được cung cấp

Một vài nhận xét chung hơn

  • Bạn có sử dụng tham chiếu tuần hoàn không?

  • Tài liệu tham khảo lười biếng khó gỡ lỗi. Đảm bảo rằng công cụ không vô tình kích hoạt độ phân giải proxy bởi e. g. gọi điện cho

    @Document
    class Book {
    
      @Id
      ObjectId id;
      String title;
      List<String> author;
    
      @Field("publisher_ac")
      @DocumentReference(lookup = "{ 'acronym' : ?#{#target} }") (1)
      Publisher publisher;
    }
    
    @Document
    class Publisher {
    
      @Id
      ObjectId id;
      String acronym;                                            (1)
      String name;
    
      @DocumentReference(lazy = true)                            (2)
      List<Book> books;
    
    }
    3