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.
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 ?
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"))});
My backend replies to find all requests:
User.find();
Like this
{ 'users' : [ user1_obj, user2_obj ] }
Ember-data is happy about it. Now if I do a simple single object find:
User.find('user1');
I have tried configuring the backend to return any of the following:
user1
{ 'user1' : user1_obj }
{ 'user' : { 'user1' : user1_obj } }
{ 'user' : user1_obj }
But none of those are working. What should I return from the backend in reply to find("obj-id") requests? According to the documentation about JSON ROOT, the right format looks like:
{ 'user' : user1_obj }
Ember does not complain about it, but the Ember Objects processed have a very strange structure, like this:
As you can see, _reference.record is referring to the top record. Also (not shown here) _data field is empty.
What could be causing that strange nesting?
EDIT
As linked by mavilein in his answer, the JSON API suggests using a different format for singular resources:
{ 'users' : [user1_obj] }
That means, the same format as for plural resources. Not sure if Ember will swallow that, I'll check now.
Following this specification, i would suspect the following:
{
'users' : [{
"id": "1",
"name" : "John Doe"
},{
"id": "2",
"name" : "Jane Doe"
}]
}
For singular resources the specification says:
Singular resources are represented as JSON objects. However, they are
still wrapped inside an array:
{
'users' : [{
"id": "1",
"name" : "John Doe"
}]
}
Using User.find() will expect the rootKey pluralized and in your content an array of elements, the response format is the following json:
{
users: [
{ id: 1, name: 'Kris' },
{ id: 2, name: 'Luke' },
{ id: 3, name: 'Formerly Alex' }
]
}
And with User.find(1) the rootKey in singular, and just one object:
{
user: {
id: 1, name: 'Kris'
}
}
Here a demo showing this working
Given a document like this:
{ "_id": {
"$oid": "4d88ca367d190a0aa4e27806" }, "Rows": [
{
"Columns": {
"Date": "Tue, 02 Aug 2011 00:00:00 GMT -04:00",
"Col2": 33
"Col3": 44
}
},
{
"Columns": {
"Date": "Mon, 17 Oct 2011 00:00:00 GMT -04:00",
"Col2": 55
"Col3": 66
}
} ], "DocName": "For My Eyes Only", "DocIdentifier": 3322445 }
and the following Map/Reduce functions:
function() {
this.Rows.forEach(function(bulkcol) {
emit(this.DocName, { TrendValue: bulkcol.Columns.Col2 });
});
};
function(key, values) {
var sum = 0;
values.forEach(function(currTrend) {
sum += currTrend.TrendValue;
});
return {DocName: key, TrendValue: sum};
};
I get the following output:
{
"_id": null,
"value": {
"DocName": null,
"TrendValue": 88
}
}
Why is the DocName null?
The problem is very much as Srdjan indicated - inside your forEach function, you don't actually have a reference to the parent document.
If you change your map function to this, it works:
m = function() {
var docName = this.DocName;
this.Rows.forEach(function(bulkcol) {
emit(docName, { TrendValue: bulkcol.Columns.Col2 });
});
};
So, assign the doc name into a variable before the loop, and then use that within it
If I'm looking at this right, and I'd like to think that I am, the this in the emit function is not what you're expecting it to be.
Since it's inside a function, that this refers to each Row, not the parent document. Try this:
function() {
this = parent;
this.Rows.forEach(function(bulkcol) {
emit(parent.DocName, { TrendValue: bulkcol.Columns.Col2 });
});
};