使用可搜索的嵌套数组设计mongodb模式。
我是来自关系数据库的Mongodb新手,我还想指出我正在使用SpringBoot和JPA。如果我要建立一个汽车分类网站,在那里我将拥有数千个用户和上百个上万个列表,我将如何设置模式?我读过一些文章说规范化nosql数据是不好的做法 不管怎样,假设我们有以下结构使用可搜索的嵌套数组设计mongodb模式。,mongodb,spring-boot,Mongodb,Spring Boot,我是来自关系数据库的Mongodb新手,我还想指出我正在使用SpringBoot和JPA。如果我要建立一个汽车分类网站,在那里我将拥有数千个用户和上百个上万个列表,我将如何设置模式?我读过一些文章说规范化nosql数据是不好的做法 不管怎样,假设我们有以下结构 User id name email Cars id make model year 我需要能够与用户一起列出许多汽车,我在示例中看到的是,它在用户中创建了一个汽车嵌套数组。这将是伟大的工作,为用户帐户,我
User
id
name
email
Cars
id
make
model
year
我需要能够与用户一起列出许多汽车,我在示例中看到的是,它在用户中创建了一个汽车嵌套数组。这将是伟大的工作,为用户帐户,我想向用户提供他们所有的汽车
我有点困惑的是车。汽车需要能够很快地被搜索到,而不需要用户信息。在sql数据库中,我通常会对汽车(年份、品牌、型号)进行搜索,然后在需要时抓取用户
在mongodb中,您是否创建了包含嵌套car数组的用户文档?或者,您是否以某种方式创建了两个文档,它们都是自动维护的,并且出于性能原因,会根据car文档进行搜索
示例代码
@Document(collection = "person")
public class Person {
@Id
private String id;
private String firstName;
private String lastName;
// @DBRef(lazy = true)
private List<Listing> listings;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
@Document(collection = "listing")
public class Listing {
@Id
public String id;
public String year;
public String make;
public String model;
public String trim;
public Listing(String year, String make, String model, String trim) {
this.year = year;
this.make = make;
this.model = model;
this.trim = trim;
}
}
@Override
public void run(String... args) throws Exception {
repository.deleteAll();
List<Listing> listings = new ArrayList<>();
Listing listing = new Listing("2008", "Ford", "Focus", "SE");
//listingRepository.save(listing);
listings.add(listing);
Person person = new Person("Alice", "Smith");
person.setListings(listings);
// save a couple of customers
repository.save(person);
person = new Person("Bob", "Smith");
listings = new ArrayList<>();
listings.add(new Listing("2018", "Chrysler", "300", "S"));
person.setListings(listings);
repository.save(person);
// fetch all customers
System.out.println("Customers found with findAll():");
System.out.println("-------------------------------");
for (Person _person : repository.findAll()) {
System.out.println(_person);
}
System.out.println();
// fetch an individual customer
System.out.println("Person found with findByFirstName('Alice'):");
System.out.println("--------------------------------");
System.out.println(repository.findByFirstName("Alice"));
System.out.println("Persons found with findByLastName('Smith'):");
System.out.println("--------------------------------");
for (Person _person : repository.findByLastName("Smith")) {
System.out.println(_person);
}
List<Listing> _listings = listingRepository.findAll();
System.out.println("listings " + _listings.size());
_listings.forEach(v -> {
System.out.println(v.toString());
});
}
@文档(collection=“person”)
公共阶层人士{
@身份证
私有字符串id;
私有字符串名;
私有字符串lastName;
//@DBRef(lazy=true)
私人名单;
公众人物(字符串名、字符串名){
this.firstName=firstName;
this.lastName=lastName;
}
}
@文档(collection=“listing”)
公共类列表{
@身份证
公共字符串id;
公共字符串年;
公共字符串制作;
公共字符串模型;
公共弦修剪;
公开上市(字符串年份、字符串品牌、字符串型号、字符串修剪){
今年=年;
make=make;
this.model=模型;
this.trim=修剪;
}
}
@凌驾
公共无效运行(字符串…参数)引发异常{
repository.deleteAll();
列表列表=新的ArrayList();
上市=新上市(“2008”、“福特”、“福克斯”、“SE”);
//listingRepository.save(列表);
列表。添加(列表);
个人=新人(“爱丽丝”、“史密斯”);
person.setListings(列表);
//拯救几个顾客
储存库。保存(个人);
人员=新人员(“鲍勃”、“史密斯”);
listings=newarraylist();
增加(新上市(“2018”、“克莱斯勒”、“300”、“S”);
person.setListings(列表);
储存库。保存(个人);
//招揽所有顾客
System.out.println(“使用findAll()找到的客户:”;
System.out.println(“------------------------------------”;
for(Person\u Person:repository.findAll()){
系统输出打印号(_人);
}
System.out.println();
//招揽个别客户
System.out.println(“使用findByFirstName('Alice'):”)找到的人;
System.out.println(“-------------------------------------”);
System.out.println(repository.findByFirstName(“Alice”);
System.out.println(“使用findByLastName('Smith'):”)找到的人;
System.out.println(“-------------------------------------”);
for(Person _Person:repository.findByLastName(“Smith”)){
系统输出打印号(_人);
}
List _listings=listingRepository.findAll();
System.out.println(“listings”+_listings.size());
_listings.forEach(v->{
System.out.println(v.toString());
});
}
根据您的实体模型,我认为您所寻找的类似于关系数据库中的多对多/一对多关系。因此,您可以在MongoDb中选择单向嵌入或双向嵌入
对于单向嵌入,您可以创建一个汽车集合,如下所示:
db.carCollection.insertMany([{
_id:1,
make: 'porcha',
model:'qwerty',
year:'2018'
},
{
_id:2,
make: 'ferrara',
model:'uiop',
year:'2018'
}])
然后,您可以继续创建用户集合,如下所示:
db.userCollection.insert({
_id:1,
user:'Tom',
email:'tom@tom.com',
car_ids:[1,2]
})
car_id是一个数组,它将保存属于用户的车辆的id
您可以通过以下方式获取属于用户的汽车(使用findOne获取用户。搜索参数应为唯一id。我认为电子邮件在此是唯一的。理想情况下,它应为用户id):
这将为您获取每个用户的所有汽车
对于仅取车,您只需执行以下操作:
db.carCollection.find({})
对于双向嵌入,可以使用类似的数组(如在用户集合中)车内收集,以便每辆车都可以向其用户识别。因此,这在某些方面与关系数据库类似,我们将车ID作为外键?是的,类似,但不相同。在面向文档的模型(如mongo)中没有外键的概念。在关系数据库中,外键约束由数据库本身强制执行,但在mongo db中,我们自己必须保持数据完整性。因此,在这种情况下,如果您删除一辆汽车,您必须确保同一事务删除其用户集合中的所有引用。我不确定您是否是spring用户,但您是否知道spring JPA是否能够处理多个文档/数据同步,或者我是否需要手动处理每个文档。
db.carCollection.find({})