I have an inspector which contains a list of object has name and type, and my custom data. Let say i wanna display my custom data base on the choice of type attribute. I can do this with 'when' but it's only if it is the simple field with specific path like "attr/type". Since it's in the list, the index vary so i dont know how to specify the path to check whether what type is chosen. Any idea for this problem ?
data: {
type : 'list',
item: {
type: 'object',
properties: {
'name' : {
type : 'text',
group : 'text',
label : 'Name',
index : 1
},
type : {
type : 'select',
group : 'text',
label : 'Type',
options: ['Text','Number','Date','Select','Text Area'],
index : 2
},
required : {
type : 'toggle',
group : 'validation',
label : 'Required',
index : 3
},
'min-length' : {
type : 'number',
group : 'validation',
min : 0,
label : 'Min Length',
index : 4
},
'max-length' : {
type : 'number',
group : 'validation',
min : 1,
label : 'Max Length',
index : 5
},
'min' : {
type : 'number',
group : 'validation',
min : 0,
label : 'Min',
index : 6
},
'max' : {
type : 'number',
group : 'validation',
min : 1,
label : 'Max',
index : 7
},
'message' : {
type : 'text',
group : 'validation',
label : 'Error message',
index : 8
},
'regex' : {
type : 'text',
group : 'validation',
label : 'Regex',
index : 9
},
'options' : {
type : 'list',
item : {
type:'object',
properties: {
'text' : {
type : 'text',
label : 'Text',
index : 1
},
'value' :{
type : 'text',
label : 'Value',
index : 2
}
}
},
group : 'validation',
label : 'Options',
index : 10
}
}
},
group : 'validation',
label : 'Input',
index : 1
}
I affraid you need to create a field for each type from the name/type collection. Similar problem is solved here:
operator: {
type: 'select',
options: ['over', 'in', 'out', 'atop', 'xor', 'arithmetic'],
},
k1: {
type: 'number',
when: { eq: { operator: 'or' } }
},
k2: {
type: 'number',
when: { eq: { operator: 'arithmetic' } }
},
k3: {
type: 'number',
when: { eq: { operator: 'xor' } }
},
k4: {
type: 'number',
when: { eq: { operator: 'over' } }
}
EDIT:
it's obvious this approach cannot be used in your case... xpath
when: { eq: { 'labels/0/type': 'Number' } } is valid but useless. It's not doable easilly so far, we set up a new issue for this. Would be nice to have something like when: { eq: { '*/type': 'Number' } } where * could be current context, so you would be able to get current index.
You have to provide inside the Attribute of particular element..
For example you need to hide the message element based on attr/type option You need to write the code like that..
'message' : {
type : 'text',
group : 'validation',
label : 'Error message',
when: { ne: { 'data/item/type': "Your Option here!!"} },
index : 8
},
Suggestions are welcome!! Thank you
Related
I have a collection named Codes. This is how the Schema is defined:
import mongoose from 'mongoose'
import autoIncrement from 'mongoose-auto-increment';
const Schema = mongoose.Schema;
const CodesSchema = mongoose.Schema(
{
configId: { type: Number },
campaignId: { type: Number },
permissions: {
all: { type: Boolean, default: false },
users: { type: [Number], default: [] }
}
)
autoIncrement.initialize(mongoose.connection);
CodesSchema.plugin(autoIncrement.plugin, { model: 'Codes', field: 'campaignId' });
export default mongoose.model('Codes', CodesSchema)
There is one query that looks like this:
const query = {
$and:[
{$or: [
{'permissions.all': true},
{'permissions.users': 12}
]},
{configId: 3}
]
};
Codes.find(query, (err, res) => {
// do something with the result
})
This works fine, but if there is a huge number of documents in the database then this query is really slow.
Is there anything I can do to improve the performance of this specific query? I'm thinking that createIndex would help, but I'm not sure if that can be applied since there are $and and $or conditions.
UPDATE
I've added indexes this way:
CodesSchema.index({configId: 1, 'permissions.all': 1, 'permissions.users': 1});
But running the query with .explain('executionStats') option returns:
{
"executionSuccess" : true,
"nReturned" : 6,
"executionTimeMillis" : 0,
"totalKeysExamined" : 10,
"totalDocsExamined" : 10,
}
Which doesn't seems right because the number of docs examined is greater than the number of docs returned.
The index itself is correct.
It must be CodesSchema.index, not Code.index.
Ensure you call Code.syncIndexes to update indexes dbside.
The "explain" part - you should check winningPlan.
If no indexes are used by the query, it should be something like
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
When the index is being used it changes to
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "OR",
"inputStages" : [
{
"stage" : "IXSCAN",
"keyPattern" : {
I have a Model : Place, where when I create the record in the Mongodb database I set some field such as :
place_name, description, capacity and in the JSON place_address all the attributes instead of latitude and longitude.
In the PlaceController.js, I have an update method where I want to update in the JSON place_address the latitude and longitude field which weren't set.
The only way to do that is to create a new JSON place_address where I get all the previous parameters and I set the latitude and longitude.
Is there an easier way to do that like : (but the following code doesn't work)
In PlaceController.js
Place.update(id, {
place_address.latitude : req.param('latitude'),
place_address.longitude : req.param('longitude')
})
For a better understanding here is the Model Place.js :
module.exports = {
attributes: {
place_name : {
type : 'string',
required : true,
},
description : {
type : 'string',
required : true,
},
capacity : {
type : 'string',
required : true,
},
place_address : {
type : 'json',
required : true,
},
office_hours: {
type : 'array'
},
conditions: {
type : 'json'
},
functions: {
type : 'array'
},
owners: {
type : 'array'
}
}
};
And here is the Controller PlaceController.js :
update: function (req,res) {
var id = req.params.id;
var placeJSON = {street_number: req.param('street_number'), street_name: req.param('street_name'), additional_info: req.param('additional_info'), postcode: req.param('postcode'), town: req.param('town'), country: req.param('country')};
if (!id) {
console.log("No id specified.");
return res.send("No id specified.",500);
}
Place.update(id, {
place_name : req.param('place_name'),
description : req.param('description'),
capacity : req.param('capacity'),
place_address : placeJSON
}).exec(function (err, updatedPlace) {
if (err) {
res.redirect('/place/edit');
}
if(!updatedPlace) {
res.redirect('/place/edit');
}
//res.redirect('/place');
res.redirect('/place/show/'+id);
});
}
populate sails function helps you express the association between collections, in your cases the Place and Coordinate can be made like this:
// create new place and coordinates
Place.create(placeParams).then((place) => {
Coordinate.create(coordianteParams).then((coordinate) => {
Place.findOne(lesson.id).populate('coordinates').then((place) => {
res.json(place);
})
})
// get place and coordinates
Place.find({}}.popupale('coordinates').then((places) => {
res.json(places)
});
this approach enables to update separately the coordinates and re-attach them to the parent (place collection in this case)
I create 2 models :
userPreferenceCategories = sequelize.define("userPreferenceCategories", {
id : {
type : Sequelize.INTEGER,
autoIncrement : true,
primaryKey : true,
allowNull : false
},
name : {
type : Sequelize.STRING,
allowNull : false
}
}, {
indexes: [
{
unique : true,
fields : ["name"]
}
],
freezeTableName : true
});
and
userPreferenceCategoryTypes = sequelize.define("userPreferenceCategoryTypes", {
id : {
type : Sequelize.INTEGER,
autoIncrement : true,
primaryKey : true,
allowNull : false
},
name : {
type : Sequelize.STRING,
allowNull : false
}
}, {
indexes: [
{
unique : true,
fields : ["name", "userPreferenceCategoryId"]
}
],
freezeTableName : true
});
With relation :
userPreferenceCategoryTypes.belongsTo(userPreferenceCategories, {
onDelete : "cascade",
onUpdate : "cascade",
foreignKey : {
field : "userPreferenceCategoryId",
allowNull : false,
}
});
one time, I create an userPreferenceCategories entry :
userPreferenceCategories.upsert({name : "cat1"});
in second time, I would like create an userPreferenceCategoryTypes associate at "cat1" like this :
userPreferenceCategoryTypes.upsert({
name : "type1",
userPreferenceCategory : {
name : "cat1"
}
}, {
include: [ {
model : userPreferenceCategories
} ]
});
but this don't work with message :
Unhandled rejection SequelizeValidationError: notNull Violation: userPreferenceCategoryId cannot be null
In fact, sequelize does not seem to add userPreferenceCategoyId attribut on sql request. How can I insert new entry in userPreferenceCategoryTypes this foreignKey of cat ? I don't execute that on series.
EDIT 1 :
I found a solution but I'm not sure if there had better : /
userPreferenceCategory.find({where: {name: "cat1"}}).then(function (cat) {
UserPreferenceCategoryType.create({
name : "type1",
userPreferenceCategoryId : cat.getDataValue("id")
});
});
It seems it's the only solution
No, because when you do a create with include, it will create the
associated instance, not associate it.
I am trying to query multiple tables which has multiple indexes and types but there is no documentation available on multi-index,multitype query in mongoosastic.
Refer this doc trying to do this same thing but with mongoosastic query.
I had the same issue. Please do the following to make it work.
Make sure you deleted the indexes:
DELETE request via postman for example: http://127.0.0.1:9200/{your_name}
Then in node JS Create a mapping like this:
var schema = new Schema({
product_name: String,
description: {
type: String,
es_type: 'multi_field',
es_fields: {
multi_field: { type: 'string', index: 'analyzed' },
untouched: { type: 'string', index: 'not_analyzed' }
}
}
});
Finally you can query like this:
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"description.multi_field" : "nog een testje"
}
}
}
}}// to use other field, change the . after description
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"description.untouched" : "nog een testje"
}
}
}
}
}
I'm trying to use meteor-collection2 to validate my collection.
I have a service, on server side :
Meteor.methods
UserSignUpService: (options) ->
# create user
Accounts.createUser options
That I call on client side :
Meteor.call 'UserSignUpService',
email: 'my.email#domain.com'
password: 'mypassword'
profile:
name: 'me'
And this is my schema :
# user profile
UserProfile = new SimpleSchema
name:
type: String
min: 1
max: 50
optional: false
# user
User = new SimpleSchema
emails:
type: [Object]
optional: false
"emails.$.address":
type: String
regEx: SimpleSchema.RegEx.Email
"emails.$.verified"
type: Boolean
createdAt:
type: Date
profile:
type: UserProfile
optional: false
services:
type: Object
optional: true
blackbox: true
# links to user collection
Meteor.users.attachSchema User
But, when user is created, there are not all fields in my mongo collection :
{ "_id" : "ikvBq95JBLXMCSnhT", "emails" : [ { "address" : "my.email#domain.com" } ] }
Whereas it should be :
{ "_id" : "WNkjGFhNkLpRR2Jex", "createdAt" : ISODate("2015-08-06T09:00:59.887Z"), "services" : { "password" : { "bcrypt" : "$2a$10$QvMLuI.Pv0bzzii3ZZP...fHfUlU9KiYfcsC2VHBf6q1OSPM6cfTW" }, "resume" : { "loginTokens" : [ { "when" : ISODate("2015-08-06T09:01:00.002Z"), "hashedToken" : "9KyqjRVSWm0nfIlS0sqODRmddlJ5GaG3mJ4+RMItOhk=" } ] } }, "emails" : [ { "address" : "my.email#domain.com", "verified" : false } ], "profile" : { "name" : "me" } }
Any idea on this problem ?
Many Thanks !
You're not actually setting the createdAt field value, try:
createdAt:
type: Date
autoValue: function(){
if this.isInsert return new Date()
else if this.isUpsert return { $setOnInsert: new Date };
else if this.isSet this.unset();
}
You can also omit optional: false in your schema since that's the default.
Also, and I suspect this is the bigger problem, not all user keys are returned to the client by default, only profile is normally published. For example you're expecting the services key but that doesn't normally come across. Look at the document in the mongo console and see what's there. You might need to publish a more comprehensive set of keys to the client.