-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Partition key from option #229
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
require('./init.js'); | ||
const _ = require('lodash'); | ||
const should = require('should'); | ||
const uuid = require('uuid/v4'); | ||
const DEFAULT_MODEL_VIEW = 'loopback__model__name'; | ||
let Product, db, connector; | ||
|
||
|
@@ -28,141 +29,188 @@ describe('cloudant - partitioned db', () => { | |
db.automigrate(done); | ||
}); | ||
|
||
it('property level - create global index by default', (done) => { | ||
Product = db.define('Product', { | ||
prodName: {type: String, index: true}, | ||
desc: {type: String}, | ||
}); | ||
db.autoupdate('Product', (err) => { | ||
if (err) return done(err); | ||
connector.getIndexes(connector.getDbName(connector), (e, results) => { | ||
if (e) return done(e); | ||
const indexes = results.indexes; | ||
const indexName = 'prodName_index'; | ||
should.exist(indexes); | ||
context('index tests', ()=> { | ||
it('property level - create global index by default', (done) => { | ||
Product = db.define('Product', { | ||
prodName: {type: String, index: true}, | ||
desc: {type: String}, | ||
}); | ||
db.autoupdate('Product', (err) => { | ||
if (err) return done(err); | ||
connector.getIndexes(connector.getDbName(connector), (e, results) => { | ||
if (e) return done(e); | ||
const indexes = results.indexes; | ||
const indexName = 'prodName_index'; | ||
should.exist(indexes); | ||
|
||
const index = _.find(indexes, function(index) { | ||
return index.name === indexName; | ||
const index = _.find(indexes, function(index) { | ||
return index.name === indexName; | ||
}); | ||
should.exist(index); | ||
index.name.should.equal(indexName); | ||
index.def.fields[0]['prodName'].should.equal('asc'); | ||
index.def.fields[1][DEFAULT_MODEL_VIEW].should.equal('asc'); | ||
// should be a global index | ||
index.partitioned.should.equal(false); | ||
done(); | ||
}); | ||
should.exist(index); | ||
index.name.should.equal(indexName); | ||
index.def.fields[0]['prodName'].should.equal('asc'); | ||
index.def.fields[1][DEFAULT_MODEL_VIEW].should.equal('asc'); | ||
// should be a global index | ||
index.partitioned.should.equal(false); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
|
||
it('index entry - create global index by default', (done) => { | ||
Product = db.define('Product', { | ||
prodName: {type: String}, | ||
desc: {type: String}, | ||
}, { | ||
indexes: { | ||
'prodName1_index': { | ||
keys: { | ||
prodName: -1, | ||
it('index entry - create global index by default', (done) => { | ||
Product = db.define('Product', { | ||
prodName: {type: String}, | ||
desc: {type: String}, | ||
}, { | ||
indexes: { | ||
'prodName1_index': { | ||
keys: { | ||
prodName: -1, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}); | ||
db.autoupdate('Product', (err) => { | ||
if (err) return done(err); | ||
connector.getIndexes(connector.getDbName(connector), (e, results) => { | ||
if (e) return done(e); | ||
const indexes = results.indexes; | ||
const indexName = 'prodName1_index'; | ||
should.exist(indexes); | ||
}); | ||
db.autoupdate('Product', (err) => { | ||
if (err) return done(err); | ||
connector.getIndexes(connector.getDbName(connector), (e, results) => { | ||
if (e) return done(e); | ||
const indexes = results.indexes; | ||
const indexName = 'prodName1_index'; | ||
should.exist(indexes); | ||
|
||
const index = _.find(indexes, function(index) { | ||
return index.name === indexName; | ||
const index = _.find(indexes, function(index) { | ||
return index.name === indexName; | ||
}); | ||
should.exist(index); | ||
index.name.should.equal(indexName); | ||
index.def.fields[0]['prodName'].should.equal('desc'); | ||
index.def.fields[1][DEFAULT_MODEL_VIEW].should.equal('desc'); | ||
// should be a global index | ||
index.partitioned.should.equal(false); | ||
done(); | ||
}); | ||
should.exist(index); | ||
index.name.should.equal(indexName); | ||
index.def.fields[0]['prodName'].should.equal('desc'); | ||
index.def.fields[1][DEFAULT_MODEL_VIEW].should.equal('desc'); | ||
// should be a global index | ||
index.partitioned.should.equal(false); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
|
||
it('index entry - ' + | ||
'create partitioned index for when `partitioned` is configured as true', | ||
(done) => { | ||
Product = db.define('Product', { | ||
prodName: {type: String}, | ||
desc: {type: String}, | ||
}, { | ||
indexes: { | ||
'prodName2_index': { | ||
partitioned: true, | ||
keys: { | ||
prodName: 1, | ||
it('index entry - ' + | ||
'create partitioned index for when `partitioned` is configured as true', | ||
(done) => { | ||
Product = db.define('Product', { | ||
prodName: {type: String}, | ||
desc: {type: String}, | ||
}, { | ||
indexes: { | ||
'prodName2_index': { | ||
partitioned: true, | ||
keys: { | ||
prodName: 1, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}); | ||
db.autoupdate('Product', (err) => { | ||
if (err) return done(err); | ||
connector.getIndexes(connector.getDbName(connector), (e, results) => { | ||
if (e) return done(e); | ||
const indexes = results.indexes; | ||
const indexName = 'prodName2_index'; | ||
should.exist(indexes); | ||
}); | ||
db.autoupdate('Product', (err) => { | ||
if (err) return done(err); | ||
connector.getIndexes(connector.getDbName(connector), (e, results) => { | ||
if (e) return done(e); | ||
const indexes = results.indexes; | ||
const indexName = 'prodName2_index'; | ||
should.exist(indexes); | ||
|
||
const index = _.find(indexes, function(index) { | ||
return index.name === indexName; | ||
const index = _.find(indexes, function(index) { | ||
return index.name === indexName; | ||
}); | ||
should.exist(index); | ||
index.name.should.equal(indexName); | ||
index.def.fields[0]['prodName'].should.equal('asc'); | ||
index.def.fields[1][DEFAULT_MODEL_VIEW].should.equal('asc'); | ||
// should be a global index | ||
index.partitioned.should.equal(true); | ||
done(); | ||
}); | ||
should.exist(index); | ||
index.name.should.equal(indexName); | ||
index.def.fields[0]['prodName'].should.equal('asc'); | ||
index.def.fields[1][DEFAULT_MODEL_VIEW].should.equal('asc'); | ||
// should be a global index | ||
index.partitioned.should.equal(true); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
|
||
it('index entry - ' + | ||
'create global index for when `partitioned` is configured as false', | ||
(done) => { | ||
Product = db.define('Product', { | ||
prodName: {type: String}, | ||
desc: {type: String}, | ||
}, { | ||
indexes: { | ||
'prodName3_index': { | ||
partitioned: false, | ||
keys: { | ||
prodName: 1, | ||
it('index entry - ' + | ||
'create global index for when `partitioned` is configured as false', | ||
(done) => { | ||
Product = db.define('Product', { | ||
prodName: {type: String}, | ||
desc: {type: String}, | ||
}, { | ||
indexes: { | ||
'prodName3_index': { | ||
partitioned: false, | ||
keys: { | ||
prodName: 1, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}); | ||
db.automigrate('Product', (err) => { | ||
if (err) return done(err); | ||
connector.getIndexes(connector.getDbName(connector), (e, results) => { | ||
if (e) return done(e); | ||
const indexes = results.indexes; | ||
const indexName = 'prodName3_index'; | ||
should.exist(indexes); | ||
|
||
const index = _.find(indexes, function(index) { | ||
return index.name === indexName; | ||
}); | ||
should.exist(index); | ||
index.name.should.equal(indexName); | ||
index.def.fields[0]['prodName'].should.equal('asc'); | ||
index.def.fields[1][DEFAULT_MODEL_VIEW].should.equal('asc'); | ||
// should be a global index | ||
index.partitioned.should.equal(false); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
db.automigrate('Product', (err) => { | ||
if (err) return done(err); | ||
connector.getIndexes(connector.getDbName(connector), (e, results) => { | ||
if (e) return done(e); | ||
const indexes = results.indexes; | ||
const indexName = 'prodName3_index'; | ||
should.exist(indexes); | ||
}); | ||
|
||
const index = _.find(indexes, function(index) { | ||
return index.name === indexName; | ||
context('findAll tests', ()=> { | ||
it('find all records by partition key from option', (done) => { | ||
Product = db.define('Product', { | ||
name: {type: String}, | ||
tag: {type: String}, | ||
}, { | ||
forceId: false, | ||
indexes: { | ||
'product_name_index': { | ||
partitioned: true, | ||
keys: { | ||
city: 1, | ||
}, | ||
}, | ||
}, | ||
}); | ||
db.automigrate('Product', () => { | ||
Product.create(SEED_DATA, function(err) { | ||
if (err) return done(err); | ||
Product.find({where: {tag: 'food'}}, {partitionKey: 'toronto'}, | ||
(err, results) => { | ||
if (err) return done(err); | ||
should.exist(results); | ||
results.length.should.equal(2); | ||
const resultTaggedFood = _.filter(results, | ||
function(r) { | ||
return r.tag === 'food'; | ||
}); | ||
resultTaggedFood.length.should.equal(2); | ||
done(); | ||
}); | ||
}); | ||
should.exist(index); | ||
index.name.should.equal(indexName); | ||
index.def.fields[0]['prodName'].should.equal('asc'); | ||
index.def.fields[1][DEFAULT_MODEL_VIEW].should.equal('asc'); | ||
// should be a global index | ||
index.partitioned.should.equal(false); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
|
||
const SEED_DATA = [ | ||
{id: `toronto: ${uuid()}`, name: 'beer', tag: 'drink'}, | ||
{id: `toronto: ${uuid()}`, name: 'salad', tag: 'food'}, | ||
{id: `toronto: ${uuid()}`, name: 'soup', tag: 'food'}, | ||
{id: `london: ${uuid()}`, name: 'beer', tag: 'drink'}, | ||
{id: `london: ${uuid()}`, name: 'salad', tag: 'food'}, | ||
{id: `london: ${uuid()}`, name: 'salad', tag: 'food'}, | ||
]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if I have a 7th record There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep, because its partitionKey is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, the name There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep they are related :)
My understanding is index is a secondary optimization for search. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just out of curious, I guess the performance of partition + where(#L196) is better than doing where on find() normally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@agnes512 Exactly, if you are interested to learn more about this feature, it's explained in https://docs.couchdb.org/en/master/partitioned-dbs/index.html.
An example: you have 200 documents in partition
US
and 300 documents in partitionCA
, when you do a global search, you find among 500 documents, but if you specifypartitionKey
asUS
and perform a partitioned search, you find among those 200 documents.