如何通过 MongoDB 中的键查询子文档映射?
How do I query a map of subdocuments by a key in MongoDB?
我创建了以下猫鼬模式来保存我从 iTunes 中提取的一些音乐数据 API:
...
const MusicAlbumSchema = new Schema({
artist_name: {
type: String,
required: 'enter an artist name'
},
album_name: {
type: String,
required: 'enter an album name'
},
artwork_url: {
type: String,
required: 'enter an artwork url'
}
});
const SearchResultSchema = new Schema({
created_date: {
type: Date,
default: Date.now
},
search: {
type: Map,
of: [ MusicAlbumSchema ]
}
});
...
SearchResultSchema
中的搜索字段以搜索查询为键(例如'The Beatles'),并将返回的结果存储为MusicAlbumSchema的子文档数组。为了测试它,我试着写了一些摩卡测试:
...
it('Creates a search result with sub-documents', done => {
const musicAlbum1 = new MusicAlbum({
artist_name: 'The Beatles',
album_name: 'Abbey Road',
artwork_url: 'www.google.com'
});
const musicAlbum2 = new MusicAlbum({
artist_name: 'The Beatles',
album_name: 'Let It Be',
artwork_url: 'www.google.com'
});
const result = new SearchResult({
search: {}
});
result.search.set('The Beatles', [musicAlbum1, musicAlbum2]);
result.save().then(() => {
SearchResult.findOne({
'The Beatles' : { $exists : true }
}).then(records => {
console.log(records);
assert(records.length === 2);
done();
});
});
});
...
我做错了什么以及如何正确查询保存的数据(特别是 SearchResultSchema 中的搜索字段)?
决定将我的架构更改为:
const MusicAlbumSchema = new Schema({
artist_name: {
type: String,
required: true
},
album_name: {
type: String,
required: true
},
artwork_url: {
type: String,
required: true
}
});
const SearchResultSchema = new Schema({
created_date: {
type: Date,
default: Date.now
},
search_query: {
type: String,
required: true,
unique: true,
dropDups: true
},
search_results: [MusicAlbumSchema]
});
– 因此,mocha 测试也发生了变化:
it('Creates a search result with sub-documents', done => {
const musicAlbum1 = new MusicAlbum({
artist_name: 'The Beatles',
album_name: 'Abbey Road',
artwork_url: 'www.google.com'
});
const musicAlbum2 = new MusicAlbum({
artist_name: 'The Beatles',
album_name: 'Let It Be',
artwork_url: 'www.google.com'
});
const result = new SearchResult({
search_query: 'The Beatles',
search_results: [musicAlbum1, musicAlbum2]
});
result.save().then(() => {
SearchResult.findOne({
search_query: 'The Beatles'
}).then(record => {
assert(record.search_results.length === 2);
done();
});
});
});
我创建了以下猫鼬模式来保存我从 iTunes 中提取的一些音乐数据 API:
...
const MusicAlbumSchema = new Schema({
artist_name: {
type: String,
required: 'enter an artist name'
},
album_name: {
type: String,
required: 'enter an album name'
},
artwork_url: {
type: String,
required: 'enter an artwork url'
}
});
const SearchResultSchema = new Schema({
created_date: {
type: Date,
default: Date.now
},
search: {
type: Map,
of: [ MusicAlbumSchema ]
}
});
...
SearchResultSchema
中的搜索字段以搜索查询为键(例如'The Beatles'),并将返回的结果存储为MusicAlbumSchema的子文档数组。为了测试它,我试着写了一些摩卡测试:
...
it('Creates a search result with sub-documents', done => {
const musicAlbum1 = new MusicAlbum({
artist_name: 'The Beatles',
album_name: 'Abbey Road',
artwork_url: 'www.google.com'
});
const musicAlbum2 = new MusicAlbum({
artist_name: 'The Beatles',
album_name: 'Let It Be',
artwork_url: 'www.google.com'
});
const result = new SearchResult({
search: {}
});
result.search.set('The Beatles', [musicAlbum1, musicAlbum2]);
result.save().then(() => {
SearchResult.findOne({
'The Beatles' : { $exists : true }
}).then(records => {
console.log(records);
assert(records.length === 2);
done();
});
});
});
...
我做错了什么以及如何正确查询保存的数据(特别是 SearchResultSchema 中的搜索字段)?
决定将我的架构更改为:
const MusicAlbumSchema = new Schema({
artist_name: {
type: String,
required: true
},
album_name: {
type: String,
required: true
},
artwork_url: {
type: String,
required: true
}
});
const SearchResultSchema = new Schema({
created_date: {
type: Date,
default: Date.now
},
search_query: {
type: String,
required: true,
unique: true,
dropDups: true
},
search_results: [MusicAlbumSchema]
});
– 因此,mocha 测试也发生了变化:
it('Creates a search result with sub-documents', done => {
const musicAlbum1 = new MusicAlbum({
artist_name: 'The Beatles',
album_name: 'Abbey Road',
artwork_url: 'www.google.com'
});
const musicAlbum2 = new MusicAlbum({
artist_name: 'The Beatles',
album_name: 'Let It Be',
artwork_url: 'www.google.com'
});
const result = new SearchResult({
search_query: 'The Beatles',
search_results: [musicAlbum1, musicAlbum2]
});
result.save().then(() => {
SearchResult.findOne({
search_query: 'The Beatles'
}).then(record => {
assert(record.search_results.length === 2);
done();
});
});
});