Hello community,
I'm trying to figure out how I can get only the value of a specific key. Let's say:
Item Number: 121225734541
transaction:: 1205737904002
Price: C $4.73
Shipping price: Free
I need to get only the value after the ":" char.
Key: Item Number, Value: 121225734541
Any ideas?
Check this out: https://jsfiddle.net/5buspznn/1/
var raw_data = 'Item Number: 121225734541\ntransaction: 1205737904002\nPrice: C $4.73\nShipping price: Free'
var data_object = {}
raw_data.split('\n').map(function (data_line) {
var parsed = data_line.match(/(.*?):(.*)/)
data_object[parsed[1]] = parsed[2].trim()
})
console.log(data_object)
returns this:
Object {
Item Number: "121225734541",
transaction: "1205737904002",
Price: "C $4.73",
Shipping price: "Free"
}
Here you go:
([^:]+):\s*([^\n]+)
# anything not :
# followed by : and whitespaces, eventually
# anything not a newline
The first capture group holds your key, the second your value.
See a demo on regex101.com.
Related
#Published var storedMedicines: [Medicine] = [
Medicine(Title: "Medicine 1", Description: "Lower blood sugar", date: .init(timeIntervalSince1970: 1664779248), isTaken: false),
Medicine(Title: "Medicine 1", Description: "Lower blood sugar", date: .init(timeIntervalSince1970: 1664880248), isTaken: false),
Medicine(Title: "Medicine 1", Description: "Lower blood sugar", date: .init(timeIntervalSince1970: 1664720990), isTaken: false),
Medicine(Title: "Medicine 1", Description: "Lower blood sugar", date: .init(timeIntervalSince1970: 1664720990), isTaken: false),
]
I want to know how can I count the "isTaken" attribute in here. I want to specifically make it said that "2 isTaken true" and 2 isTaken false"
There are two many ways to do this.
Using filter.
let trueCount = storedMedicines.filter(\.isTaken).count
let falseCount = storedMedicines.count - trueCount
Using reduce.
let trueCount = storedMedicines.reduce(0, { $0 + ($1.isTaken ? 1 : 0) })
let falseCount = storedMedicines.count - trueCount
I have a mongodb collection named "users" with a few thousand users. Due to lack of validation users were able to create "username" with spaces in it. I.e, user was able to create username such as "I am the best" or " I am the best" or "I am the best " and so on. Since "username" field was not used in any form in the system it was just ok until now.
From now on the client wants to use "username" field finally, that is, to make urls such as "https://example.com/profile/{username}".
The problem is this that the "username" field values have spaces at the beginning, middle and at the end as shown above, on random. So I want to remove them using a query.
I am able to list all users using:
db.users.find({username:{ "$regex" : ".*[^\S].*" , "$options" : "i"}}).pretty();
What is the best approach to remove all spaces in username field and save them back? I am not sure how to update them in a single query.
Help is appreciated!
Ps. I actually need to write a code block to replace these usernames while checking for "existing" usernames so that there is no duplicate but I would still want to know how I do it if I need to do it using mongodb query.
The problem is this that the "username" field values have spaces at the beginning, middle and at the end as shown above, on random. So I want to remove them using a query.
MongoDB 4.4 or Above:
You can use update with aggregation pipeline starting from MongoDB 4.2,
$replaceAll starting from MongoDB 4.4
it will find white space and replace with blank
db.users.update(
{ username: { $regex: " " } },
[{
$set: {
username: {
$replaceAll: {
input: "$username",
find: " ",
replacement: ""
}
}
}
}],
{ multi: true }
)
Playground
MongoDB 4.2 or Above:
You can use update with aggregation pipeline starting from MongoDB 4.2,
$trim to remove white space from both left and right
$split to split username by space and result array
$reduce to iterate loop of above split result
$concat to concat username
db.users.update(
{ username: { $regex: " " } },
[{
$set: {
username: {
$reduce: {
input: { $split: [{ $trim: { input: "$username" } }, " "] },
initialValue: "",
in: { $concat: ["$$value", "$$this"] }
}
}
}
}],
{ multi: true }
)
Playground
MongoDB 3.6 or Above:
find all users and loop through forEach
replace to apply pattern to remove white space, you can update pattern as per your requirement
updateOne to update updated username
db.users.find({ username: { $regex: " " } }, { username: 1 }).forEach(function(user) {
let username = user.username.replace(/\s/g, "");
db.users.updateOne({ _id: user._id }, { $set: { username: username } });
})
I am trying to search in a collection by a word. So I have record like this:
{
"_id" : ObjectId("5ec2e9d0543e75377e9f3981"),
"text" : "işlemci",
"question" : ObjectId("5ec2c3f36700e13311592917"),
"createdAt" : ISODate("2020-05-18T20:02:24.641+0000"),
"updatedAt" : ISODate("2020-05-18T20:02:24.641+0000"),
"__v" : NumberInt(0)
}
And i am using following query to find that entry:
var answer = "islemci"
const answerRegex = new RegExp(answer, 'i');
const answers = await Answer
.find({
text: answerRegex,
question: questionId
})
.populate('question', 'text -_id')
.select('text question');
It doesn't find any records, because we passed "islemci" value to our answer variable. If i try with "işlemci" it finds the entry.
How can i ignore the Turkish characters when i am searching?
Turkish characters: https://en.wikipedia.org/wiki/Wikipedia:Turkish_characters
Language-specific rules for strings comparison can be handled using collation. Basically in your case you can use en_US for locale and specify strength 1 which will ignore any non-english characters.
1 Primary level of comparison. Collation performs comparisons of the base characters only, ignoring other differences such as diacritics and case.
In mongoose collation can be specified on the schema level:
const yourSchema = new Schema(
{
text: String,
question: Schema.Types.ObjectId,
createdAt: Date,
updatedAt: Date,
},
{ collation: { locale: 'en_US', strength: 1 } }
);
Whenever you call .find like this:
let doc = await Model.find({ text: 'islemci' });
mongoose will run following query:
db.col.find({ text: 'islemci' }, { collation: { locale: 'tr', strength: 1 }, projection: {} })
It works for equality comparisons but unfortunately is not applicable for $regex:
The $regex implementation is not collation-aware
I am so sorry, but after one day researching and trying all different combinations and npm packages, I am still not sure how to deal with the following task.
Setup:
MongoDB 2.6
Node.JS with Mongoose 4
I have a schema like so:
var trackingSchema = mongoose.Schema({
tracking_number: String,
zip_code: String,
courier: String,
user_id: Number,
created: { type: Date, default: Date.now },
international_shipment: { type: Boolean, default: false },
delivery_info: {
recipient: String,
street: String,
city: String
}
});
Now user gives me a search string, a rather an array of strings, which will be substrings of what I want to search:
var search = ['15323', 'julian', 'administ'];
Now I want to find those documents, where any of the fields tracking_number, zip_code, or these fields in delivery_info contain my search elements.
How should I do that? I get that there are indexes, but I probably need a compound index, or maybe a text index? And for search, I then can use RegEx, or the $text $search syntax?
The problem is that I have several strings to look for (my search), and several fields to look in. And due to one of those aspects, every approach failed for me at some point.
Your use case is a good fit for text search.
Define a text index on your schema over the searchable fields:
trackingSchema.index({
tracking_number: 'text',
zip_code: 'text',
'delivery_info.recipient': 'text',
'delivery_info.street': 'text',
'delivery_info.city': 'text'
}, {name: 'search'});
Join your search terms into a single string and execute the search using the $text query operator:
var search = ['15232', 'julian'];
Test.find({$text: {$search: search.join(' ')}}, function(err, docs) {...});
Even though this passes all your search values as a single string, this still performs a logical OR search of the values.
Why just dont try
var trackingSchema = mongoose.Schema({
tracking_number: String,
zip_code: String,
courier: String,
user_id: Number,
created: { type: Date, default: Date.now },
international_shipment: { type: Boolean, default: false },
delivery_info: {
recipient: String,
street: String,
city: String
}
});
var Tracking = mongoose.model('Tracking', trackingSchema );
var search = [ "word1", "word2", ...]
var results = []
for(var i=0; i<search.length; i++){
Tracking.find({$or : [
{ tracking_number : search[i]},
{zip_code: search[i]},
{courier: search[i]},
{delivery_info.recipient: search[i]},
{delivery_info.street: search[i]},
{delivery_info.city: search[i]}]
}).map(function(tracking){
//it will push every unique result to variable results
if(results.indexOf(tracking)<0) results.push(tracking);
});
Okay, I came up with this.
My schema now has an extra field search with an array of all my searchable fields:
var trackingSchema = mongoose.Schema({
...
search: [String]
});
With a pre-save hook, I populate this field:
trackingSchema.pre('save', function(next) {
this.search = [ this.tracking_number ];
var searchIfAvailable = [
this.zip_code,
this.delivery_info.recipient,
this.delivery_info.street,
this.delivery_info.city
];
for (var i = 0; i < searchIfAvailable.length; i++) {
if (!validator.isNull(searchIfAvailable[i])) {
this.search.push(searchIfAvailable[i].toLowerCase());
}
}
next();
});
In the hope of improving performance, I also index that field (also the user_id as I limit search results by that):
trackingSchema.index({ search: 1 });
trackingSchema.index({ user_id: 1 });
Now, when searching I first list all substrings I want to look for in an array:
var andArray = [];
var searchTerms = searchRequest.split(" ");
searchTerms.forEach(function(searchTerm) {
andArray.push({
search: { $regex: searchTerm, $options: 'i'
}
});
});
I use this array in my find() and chain it with an $and:
Tracking.
find({ $and: andArray }).
where('user_id').equals(userId).
limit(pageSize).
skip(pageSize * page).
exec(function(err, docs) {
// hooray!
});
This works.
I have a custom regex method:
$.validator.addMethod(
"dateRegex",
function(value, element, regexp) {
var re = new RegExp(regexp);
return this.optional(element) || re.test(value);
},
"Date must be in the format MM/DD/YYYY"
);
I've got jQuery validation on a date field that looks like this:
rules:
date:
{
required: true,
dateRegex: '^(0[1-9]|1[012])[- //.](0[1-9]|[12][0-9]|3[01])[- //.](19|20)\d\d$',
maxlength: 10
}
}
messages: {
lossDate: {
required: "Unable to proceed, search field is empty"
}
}
When I enter a valid date, for example 08/06/2013, "Date must be in the format MM/DD/YYYY" is displayed. Does anyone see a mistake in my regex, or is the problem outside of that?
The test data passes here: http://regexpal.com/
Also, I have the following working in my app:
$.validator.addMethod(
"regex",
function(value, element, regexp) {
var re = new RegExp(regexp);
return this.optional(element) || re.test(value);
},
"Invalid number of characters entered."
);
number:
{
required: true,
regex: '^(.{7}|.{9}|.{11}|.{12}|.{15})$'
},...
I guess that plugin doesn't want strings for regexes. Instead of a string literal, put a regex literal:
…,
dateRegex: /^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d$/,
…
You also can simplify the function then:
function(value, element, regexp) {
return this.optional(element) || regexp.test(value);
}