I am getting an error while using $regex in mongoose aggregation query . I am getting an invalid operator with error no 15999 . Please help guys.
{ $match: { "_id": ObjectId(req.headers.token) } }, {
$project: {
inventory: {
$filter: {
input: '$inventory',
as: 'inventory',
cond: {$or:[{"$$inventory.item":new RegExp('^'+req.query.text+'$', "i")},{"$$inventory.sku":new RegExp('^'+req.query.text+'$', "i")}]}
}
},
_id: 0
}
}
You can use regex in $match and you will get your result as in this example
Pincodes.aggregate([
{ "$match": { "district": new RegExp('^' + req.query.district, "i") }
},
{ "$group": { "_id": "$district" } }])
.exec((err, data) => {
if (err) {
res.status(500).json({
data: err
})
}
else {
res.status(200).json({
data: data
})
}
})
Doing just agg.match({'<fieldName'>:new RegExp('^' + req.query.district, "i")}) didnt work for me
I had to use eval in the solution.
if you are JSON.stringifying the aggregate query to see the output you won't see the effect of eval. Eval will have an effect later on when passed down to mongo.
agg.match({'<fieldName'>:eval(new RegExp('^' + req.query.district, "i"))});
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();
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 ?
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 have a table that has userId as the PK and a single attribute called userToken.
I have written a batchGet() function to return all the userTokens for specific userIds, however it returns it like this:
[ { userToken: '1234' },
{ userToken: '5678' } ]
I'd like it to just return the values since I already know what the attribute name will be:
['1234', '5678']
How would I go about doing so?
const params = {
RequestItems: {
UserTokens: {
Keys: userIds,
AttributesToGet: [
'userToken'
]
}
}
};
db.batchGet(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log(data.Responses);
sendNotifications(data.Responses);
}
});
DynamoDB always returns the attribute name and value.
You can easily filter this on the client side.
val = [ { userToken: '1234' }, { userToken: '5678' } ];
reducer = (accumulator, currentVal) => {
accumulator.push(currentVal.userToken);
return accumulator;
}
console.log(val.reduce(reducer, []));
In the data bellow, I would like to find the reminder where _id=abc1 and the month is 1. The date stored in db is text.
I try to use this command but it have error: db.check.find( {_id:"abc1"}, { reminder: { $regex: {date:2015-1/} }} ).pretty();
How can I do it?
The expected result is { date: "2005-1-5", event: "MeetingB" }, { date: "2005-1-4", event: "MeetingA" }
{
_id: "abc1",
reminder:[
{
date: "2005-1-5",
event: "MeetingB"
},
{
date: "2005-1-4",
event: "MeetingA"
},
{
date: "2005-2-4",
event: "MeetingA"
}
]
}
{
_id: "abc2",
reminder:[
{
date: "2005-1-5",
event: "MeetingB"
}
]
}
It think you have 2 solutions :
The first one is to aggregate your search in another to get
only the month.
Query on the date
With this example (I haven't tested but it should looks like this):
db.check.find( {
$and: [
{ "_id": { $in: ["abc1"] } },
{ "reminder.date": { $in: [/2005-1*/] } }
]
} );
You cannot use regex in a in and you have to use JavaScript regex
However it will return the full object and not a partial object as apparently you want to.