Im implementing a mongodb search.
The search performs a find on field values:
[{
value: "my.string.here"
}, {
value: "my other here"
}{
...
}]
When i enter "my" both entries are found. What have my query to look like to ignore the dots on the first entry? So when i enter "my string" the first element gets returned?
Actually it works only when i enter "my.string" which is not nice.
let limit = Number(req.query.limit || 100);
let skip = Number(req.query.skip || 0);
collection.find({
$or: [{
value: new RegExp(req.body.search, "gi")
}, {
tags: {
$in: req.body.search.split(",").map((val) => {
return new RegExp(val, "gi")
})
}
}]
}).skip(skip).limit(limit).toArray((err, result) => {
if (err) {
res.status(500).json(err);
} else {
res.status(200).json(result);
}
});
EDIT:
A solution could look like this:
let query = {
$or: [{
name: new RegExp(req.body.search, "gi")
}, {
tags: {
$in: req.body.search.split(",").map((val) => {
return new RegExp(val, "gi")
})
}
}, {
name: new RegExp(req.body.search.split(' ').join('.'), "gi")
}, {
name: new RegExp(req.body.search.split(' ').join('_'), "gi")
}, {
name: new RegExp(req.body.search.split(' ').join('-'), "gi")
}]
};
But i find it ugly and not elegant. Is there a better way to do this ?
Related
I have been trying for hours to perform a DynamoDB DeleteRequest using BatchWriteItemCommand but I keep getting the following error:
Error ValidationException: 1 validation error detected: Value null at 'requestItems.td_notes_sdk.member.1.member.deleteRequest.key' failed to satisfy constraint: Member must not be null
This is what my table looks like:
Partition key: user_id (string)
Sort key: timestamp (number)
DynamoDB Screenshot
This is what my code looks like:
// Import required AWS SDK clients and commands for Node.js
import {
DynamoDBClient,
BatchWriteItemCommand,
} from "#aws-sdk/client-dynamodb";
// Set the parameters
export const params = {
RequestItems: {
"td_notes_sdk": [
{
DeleteRequest: {
Item: {
Key: {
user_id: { S : "bb" },
timestamp: { N : 2 },
},
},
},
},
],
},
};
export const run = async () => {
const ddbClient = new DynamoDBClient({ region: "us-east-2" });
try {
const data = await ddbClient.send(new BatchWriteItemCommand(params));
console.log("Success, items inserted", data);
return data;
} catch (err) {
console.log("Error", err);
}
};
run();
Here are some resources that I've been trying to follow along with:
Resource 1: Writing items in Batch Example
Resource 2: AWS Javascript SDK v3 Documentation
Update: BatchWrite PutRequest work with the code below, so I know that the structure of my keys/attributes is closer to being correct. Still does not work for DeleteRequest.
export const params = {
RequestItems: {
"td_notes_sdk": [
{
PutRequest: {
Item: {
user_id: { "S": "bb" },
timestamp: { "N": "5" },
},
},
},
],
},
};
You don't supply an Item when deleting an item. You supply a Key.
Here is a working example:
const params_delete = {
RequestItems: {
"td_notes_sdk": [
{
DeleteRequest: {
Key: {
user_id: { S: "bb" },
timestamp: { N: "2" },
},
},
},
],
},
};
const delete_batch = async () => {
const ddbClient = new DynamoDBClient({ region: "us-east-2" });
try {
const data = await ddbClient.send(new BatchWriteItemCommand(params_delete));
console.log("Success, item deleted");
return data;
} catch (err) {
console.log("Error", err);
}
};
delete_batch();
I would like to use the checkSchema method instead of what I am currently doing with all the checks on the post route in an array. The problem I have is I can't find good documentation on the syntax used in the object for each key. The doc page for schema validation (https://express-validator.github.io/docs/schema-validation.html) gives one example but no links to all the syntax that defines all the attributes you can use (isInt, toInt, isUppercase, rtrim, etc.) I have searched high and low for the docs that tell you everything you can use there but no luck. Can someone point me in the right place?
express-validator is a set of express.js middlewares that wraps validator.js validator and sanitizer functions.
you can find all the rules available in the link above.
here is a good example how it's used with checkSchema:
import { checkSchema, validationResult } from 'express-validator'
const schema = {
id: {
isFloat: true,
// Sanitizers can go here as well
toFloat: true,
errorMessage: "must be a valid number"
},
first_name: {
exists: {
errorMessage: "first_name is required"
},
isLength: {
errorMessage: "first_name has invalid length",
options: {
min: 1
}
}
},
middle_name: {
optional: {
options: { nullable: true, checkFalsy: true }
}
},
last_name: {
exists: {
errorMessage: "last_name is required"
},
isLength: {
errorMessage: "last_name has invalid length",
options: {
min: 1
}
}
},
date_of_birth: {
isISO8601: {
errorMessage: `date of birth is not a valid iso date`
},
isBefore: {
date: "01-01-2000",
errorMessage: `should be less than 01-01-2000`
},
isAfter: {
date: "01-01-1970",
errorMessage: `should be greater than 01-01-1970`
}
},
email: {
exists: {
errorMessage: "email is required"
},
isEmail: {
errorMessage: "email is invalid"
}
},
current_country_of_residence: {
exists: {
errorMessage: "current_country_of_residence is required",
options: {
checkNull: true,
checkFalsy: true
}
}
},
current_city_of_residence: {
exists: {
bail: true,
errorMessage: "current_city_of_residence is required"
},
isMongoId: {
errorMessage: "current_city_of_residence is has invalid id for"
}
},
email: {
isEmail: { errorMessage: 'email is not a valid email' },
isLength: { errorMessage: 'email has invalid length', options: { min: 1 } }
},
skills: {
isArray: {
errorMessage: `invalid value for skills`,
options: {
min: 3,
max: 5
}
},
isIn: {
options: ["java", "C++", "javascript"],
errorMessage: `allowed values for skills are: ${["java", "C++", "javascript"]}`
},
custom: {
options: (values) => {
const unique_values = new Set(values)
if (unique_values.size !== values.length) {
return Promise.reject()
}
return Promise.resolve()
},
errorMessage: `you can't add duplicated`
},
customSanitizer: {
options: async (value, { req }) => {
return value
}
}
}
}
const validate = () => {
return [
checkSchema(schema),
(req, res, next) => {
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.mapped() })
}
next()
}
]
}
export default validate()
Find items containing a whole word.
const queryparam = 'microsoft';
mongoose.model('tag').find({name: { $regex: new RegExp("\w"+queryparam+"\w" ), '$options': 'i' }});
// tag collection
[
{
name: 'Microsoft word" // this should be returned by query
},
{
name: 'Microsoft-word" // this should not be returned by query
}
]
It's not working.
Try this (thanks to #Toto):
db.tag.find({
name: {
"$regex": "\\bMicrosoft\\b\\s",
"$options": "i"
}
})
MongoPlayground
I'm trying to make use of the RadDataForm using NativeScript-Vue to develop a relatively long form.
My form elements are being defined and grouped programmatically via json. I would like to have the groups start in a minimized / collapsed state for the user experience.
The NativeScript-Vue docs for this feature are very sparse. Angular documentation is deeper so I went there for help, but clicking thru to the "collapsed" API reference results in a 404 from this page.
I'm running it from the Playground to test functionality using the following code:
<template>
<Page class="page">
<ActionBar title="Home" class="action-bar">
<ActionItem icon="font://" class="fa" />
<ActionItem icon="font://\uf07a" class="fa" />
</ActionBar>
<RadDataForm :source="person" :metadata="groupMetaData"
#groupUpdate="onGroupUpdate" />
</Page>
</template>
<script>
import Vue from "nativescript-vue";
import RadDataForm from "nativescript-ui-dataform/vue";
Vue.use(RadDataForm);
export default {
data() {
return {
person: {
name: "John",
age: 23,
email: "john#company.com",
city: "New York",
street: "5th Avenue",
streetNumber: 11
},
groupMetaData: {
// propertyGroup: [{
// "Address": {
// 'collapsed' = true,
// },
// // {
// // "Main Info": 'collapsed',
// }
// ],
propertyAnnotations: [{
name: "city",
index: 3,
groupName: "Address",
editor: "Picker",
valuesProvider: [
"New York",
"Washington",
"Los Angeles"
]
},
{
name: "street",
index: 4,
groupName: "Address"
},
{
name: "streetNumber",
index: 5,
editor: "Number",
groupName: "Address"
},
{
name: "age",
index: 1,
editor: "Number",
groupName: "Main Info"
},
{
name: "email",
index: 2,
editor: "Email",
groupName: "Main Info"
},
{
name: "name",
index: 0,
groupName: "Main Info"
}
]
}
};
},
methods: {
onGroupUpdate: function(args) {
let nativeGroup = args.group;
if (args.ios) {
nativeGroup.collapsible = true;
// nativeGroup.collapsed = true;
} else {
nativeGroup.setExpandable(true);
// nativeGroup.collapsed;
// nativeGroup.collapsed(true);
// nativeGroup.collapsed;
}
// console.log(JSON.stringify(nativeGroup));
}
}
};
</script>
<style scoped>
.home-panel {
vertical-align: center;
font-size: 20;
margin: 15;
}
.description-label {
margin-bottom: 15;
}
</style>
My assumption was to address this in the OnGroupUpdate method, but I'm not getting where I need to be (you can see a few attempts that are commented out).
The goal is to have this view load with minimized groups so that the user can expand the different form groups that s/he wishes to work on in sequence.
Playground link: https://play.nativescript.org/?id=XLKFoC&template=play-vue&v=14
Thanks for any help
I think what you actually need is nativeGroup.setIsExpanded(false);
exports.onGroupUpdate = (args) => {
if (app.ios) {
let nativeGroup = args.group;
nativeGroup.collapsible = true;
} else {
let nativeGroup = args.group;
nativeGroup.setExpandable(true);
//in this example i only expand one group.
if (args.groupName !== "SERVICE INFORMATION") {
nativeGroup.setIsExpanded(false)
}
}
}
I'm trying to have a group of 3 radio buttons (each button in different column but the same row) in my Kendo grid but without success. I looked at the Kendo RowTemplate doc, but it's not directing me to any solution.
it works fine with checkboxes, but when i change the template to "radio" type, it changes to checkbox the second I click the edit button. any thoughts?
below is my kendoGrid properties, I put ** next to the 'template' line in the field property.
div.kendoGrid({
dataSource:
{ error: function (e) {
alert("An error occured: "+ e.xhr.responseText);
this.cancelChanges();
},
type:"json",
transport: {
read: {
url: "/users/read",
cache: false,
dataType: "json"
},
update: {
url: function(user){
var grid = $("#grid").data("kendoGrid");
var model = grid.dataItem(grid.select());
var roleIs;
if (user.Admin) {
roleIs="admin"
}
else if (user.Manager) {
roleIs="manager"
}
else if (user.User) {
roleIs="user"
};
return "users/update/"+model.id+"/"+roleIs+"/"+user.name
},
type: "PUT"
},
destroy: {
url: function(user){
return "/users/destroy/"+user.id+"/"+user.name
},
type: "DELETE"
},
create: {
url: function(user){
var roleIs;
if (user.Admin) {
roleIs="admin"
}
else if (user.Manager) {
roleIs="manager"
}
else if (user.User) {
roleIs="user"
};
return "users/create/"+user.login+"/"+user.name+"/"+roleIs+"/"
},
type: "POST"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
}
},
schema: {
model:
{ id: "id",
fields: {
id:{ type: "number",editable: false},
role:{ type: "string"},
login: { type: "string",editable: false},
name:{type: "string",editable: false},
Admin: { type: "boolean"},
Manager: { type: "boolean"},
User: { type: "boolean"}
}
}
},
pageSize: 30,
serverPaging: false,
serverFiltering: false,
serverSorting: false
},
selectable: "row",
navigatable: true,
pageable: true,
height: 400,
columns: [//{field: "id"},
{
field: "name",
title:"User Name",
filterable: true,
nullable: false,
editable: false
},{
field: "Admin",
**template: '<input type="checkbox" #= Admin ? "checked=checked" : "" # disabled="disabled"></input>'**,
width: 75
},{
field: "Manager",
**template: '<input type="checkbox" #= Manager ? "checked=checked" : "" # disabled="disabled"></input>'**,
width: 75
},{
field: "User",
**template: '<input type="checkbox" #= User ? "checked=checked" : "" # disabled="disabled"></input>',**
width: 75
},{
command: ["edit", "destroy"], title: "", width: "195px"
}],
editable:{mode: "inline"}
});
}
}
}
The formatting for edition is controlled by columns.editor
You need to write an editor function that defines the input as a radio button.