如何在 Firestore 中加入多个文档?
How to join multiple documents in a Firestore?
我有一个具有以下结构的 Firestore 数据库:
用户
- [uid]
- 姓名:'User one'
艺术家
- [uid]
- 风格:'Pop teste'
- user_uid: [uid]
在我的服务中我有
constructor(private afu: AngularFireAuth, private afs: AngularFirestore, private storage: AngularFireStorage) {
this.usersCollection = afs.collection<User>('users');
this.users = this.usersCollection.valueChanges();
}
getUsers() {
return this.users = this.usersCollection.snapshotChanges()
.pipe(map(changes => {
return changes.map(action => {
const data = action.payload.doc.data() as User;
return data
});
}));
}
用户和艺术家之间如何加入?
使用 combineLatest
是一个很好的方法。由于 user_uid 在用户上不存在,我将 idField 添加到用户作为 user_uid。先查看代码,然后阅读下面的解释。
import { Component, OnInit } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { Observable, combineLatest } from 'rxjs';
interface User {
name: string;
user_uid: string;
}
interface Artist {
style: string;
user_uid: string;
}
interface Joined {
user_uid: string;
name: string;
style: string;
}
@Component({
selector: 'test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})
export class TestComponent implements OnInit {
users$: Observable<User[]>;
artists$: Observable<Artist[]>;
joined$: Observable<Joined[]>;
constructor(private afs: AngularFirestore){}
ngOnInit(){
this.users$ = this.afs.collection<User>('users').valueChanges({idField: 'user_uid'});
this.artists$ = this.afs.collection<Artist>('artists').valueChanges();
this.joined$ = combineLatest(this.users$, this.artists$, (users, artists) => {
const joinedAsMap: Map<string, Joined> = new Map(artists.map(oneArtist => [oneArtist.user_uid, { ...{name: null} , ...oneArtist}]));
users.forEach(one => joinedAsMap.set(one.user_uid , {...{name: one.name}, ...joinedAsMap.get(one.user_uid) } ));
const joined: Joined[] = Array.from(joinedAsMap.values());
return joined;
});
}
}
- 创建连接界面
- 获取两个可观察值
- 使用最新的组合
- 构建一个以 uid 为键,艺术家为值的地图。将名称设置为 null 以便类型可以工作。使用展开运算符合并一些对象。
- 遍历用户并将用户信息添加到每个键的值
- 从 map 的值构建连接数组
- return 值
您可以通过不同的方式来执行此操作,但使用 es6 映射是简化某些事情的好方法。此外,没有机会使用真实数据库进行测试,因此您可能需要验证。此外,这都在用于演示的组件中。您肯定可以在服务中执行此操作。
我有一个具有以下结构的 Firestore 数据库:
用户
- [uid]
- 姓名:'User one'
- [uid]
艺术家
- [uid]
- 风格:'Pop teste'
- user_uid: [uid]
- [uid]
在我的服务中我有
constructor(private afu: AngularFireAuth, private afs: AngularFirestore, private storage: AngularFireStorage) {
this.usersCollection = afs.collection<User>('users');
this.users = this.usersCollection.valueChanges();
}
getUsers() {
return this.users = this.usersCollection.snapshotChanges()
.pipe(map(changes => {
return changes.map(action => {
const data = action.payload.doc.data() as User;
return data
});
}));
}
用户和艺术家之间如何加入?
使用 combineLatest
是一个很好的方法。由于 user_uid 在用户上不存在,我将 idField 添加到用户作为 user_uid。先查看代码,然后阅读下面的解释。
import { Component, OnInit } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { Observable, combineLatest } from 'rxjs';
interface User {
name: string;
user_uid: string;
}
interface Artist {
style: string;
user_uid: string;
}
interface Joined {
user_uid: string;
name: string;
style: string;
}
@Component({
selector: 'test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})
export class TestComponent implements OnInit {
users$: Observable<User[]>;
artists$: Observable<Artist[]>;
joined$: Observable<Joined[]>;
constructor(private afs: AngularFirestore){}
ngOnInit(){
this.users$ = this.afs.collection<User>('users').valueChanges({idField: 'user_uid'});
this.artists$ = this.afs.collection<Artist>('artists').valueChanges();
this.joined$ = combineLatest(this.users$, this.artists$, (users, artists) => {
const joinedAsMap: Map<string, Joined> = new Map(artists.map(oneArtist => [oneArtist.user_uid, { ...{name: null} , ...oneArtist}]));
users.forEach(one => joinedAsMap.set(one.user_uid , {...{name: one.name}, ...joinedAsMap.get(one.user_uid) } ));
const joined: Joined[] = Array.from(joinedAsMap.values());
return joined;
});
}
}
- 创建连接界面
- 获取两个可观察值
- 使用最新的组合
- 构建一个以 uid 为键,艺术家为值的地图。将名称设置为 null 以便类型可以工作。使用展开运算符合并一些对象。
- 遍历用户并将用户信息添加到每个键的值
- 从 map 的值构建连接数组
- return 值
您可以通过不同的方式来执行此操作,但使用 es6 映射是简化某些事情的好方法。此外,没有机会使用真实数据库进行测试,因此您可能需要验证。此外,这都在用于演示的组件中。您肯定可以在服务中执行此操作。