use modifier $addToSet, $push or $pull with feathersjs and NeDB - feathersjs

How can I use the modifiers $addToSet, $pull or $push with a NeDB adapter for feathersjs? Following did not work and I cannot find anything in the documentation.
service('projects').update("<id>", { $addToSet: { assignedIds: "<newId>" } });
service('projects').patch("<id>", { $addToSet: { assignedIds: "<newId>" } });
service('projects').update("<id>", { query: { $addToSet: { assignedIds: "<newId>" } } });
I also tried to put the operator in the params like this (as stated in the document)
service('projects').update("<id>", { }, {
query: { $addToSet: { assignedIds: "<newId>" } }
});
But the only thing I got back is unknown logical operator $addToSet

As per comment, this was a bug in featherjs that got patched

Related

get difference between two dates in $project

Trying to project the date difference between two dates, but I am getting error -
Invalid $project :: caused by :: Unknown expression $dateDiff
db.books.aggregate([{
$project:{
Date_diff:
{$dateDiff:{
start_dt:'$borrowers_list.borrowed_dt',
endDate:'$borrowers_list.return_dt',
unit: "day"
}
}
}
}])
The json document structure is like this -
_id:6188a5283543f7cc2f77c73f
branch_id:1
borrowers_list:Object
0:Object
borrowed_dt:2021-08-15T06:00:00.000+00:00
card_no:"ID000067"
return_dt:2021-08-25T06:00:00.000+00:00
I have no idea why the error is unknown expression $dateDiff, as my syntax is correct. Does anyone have any suggestions?
Based on your provided JSON document, the document should be as below (correct me if it is incorrect):
{
_id: ObjectId("6188a5283543f7cc2f77c73f"),
branch_id: 1,
borrowers_list: {
0: {
borrowed_dt: ISODate("2021-08-15T06:00:00.000+00:00"),
card_no: "ID000067",
return_dt: ISODate("2021-08-25T06:00:00.000+00:00")
}
}
}
]
There is no start_dt in $dateFiff field, it is startDate.
Query
db.collection.aggregate([
{
$project: {
Date_diff: {
$dateDiff: {
startDate: "$borrowers_list.0.borrowed_dt",
endDate: "$borrowers_list.0.return_dt",
unit: "day"
}
}
}
}
])
Note: Above query will perform the $dateDiff for the first document in borrowers_list.
Sample Mongo Playground
In case you need to iterate each document (with key-value pair) in borrowers_list to perform $dateDiff.
$set - Convert from object to array (via $objectToArray) for borrowers_list to new field borrowers.
$set - Iterate each document in borrowers array (1) and perform $dateDiff.
$project - Decorate the output document, convert Date_diff from array to object (via $objectToArray).
Query
db.collection.aggregate([
{
$set: {
borrowers: {
"$objectToArray": "$borrowers_list"
}
}
},
{
$set: {
Date_diff: {
$map: {
input: "$borrowers",
as: "b",
in: {
k: "$$b.k",
v: {
$dateDiff: {
startDate: "$$b.v.borrowed_dt",
endDate: "$$b.v.return_dt",
unit: "day"
}
}
}
}
}
}
},
{
$project: {
Date_diff: {
"$arrayToObject": "$Date_diff"
}
}
}
])
Sample Mongo Playground (Iterate document with key-value pair)

GraphQL in Gatsbyjs - Only Return Data Which Contains a Particular Field

I am using GraphQL within the GatsbyJs framework.
I have multiple files with JSON data. The structure of data is similar to this:
{
...,
"sections" / "menuSections"
}
That last field can be either 'sections' or 'menuSections' in each file. My current graphQL query looks like this:
{
allDataJson {
nodes {
menuSections
}
}
}
This query returns the correct 'menuSections', however, data-files which do not have 'menuSections' are returned as null. How can I get GraphQL to only return data from files which contain 'menuSections', i.e. how to return data within which 'menuSections' exist. I am looking for an operator like $exists.
if sections & menuSections are string or arrays of string, maybe you can filter for null:
{
"menuSections": "..."
}
// query
{
allDataJson(filter: {
menuSections: {
ne: null
}
}) {
nodes {
menuSections
}
}
}
If they are object, you can still filter for null, but it has to be applied to one of the field inside that object. If your objects don't have a common field, this won't work:
{
"menuSections": {
"menuSectionField": "..."
}
}
// query
{
allDataJson(filter: {
menuSections: {
menuSectionField: {
ne: null
}
}
}) {
nodes {
menuSections
}
}
}
If they are array of objects, you can do the same thing but with elemMatch:
{
"menuSections": [
{ "menuSectionField": "..." },
{ "other": "..." }
]
}
// query
allDataJson(filter: {
menuSections: {
elemMatch: {
menuSectionField: {
ne: null
}
}
}
}) { ... }
Worst case worst, I think you might be able to define some sort of custom types that ensure existence of menuSections so you can query allDataWithMenuSections etc., but if filter works it's much simpler.
It looks like there isn't an $exists operator in GraphQL. Instead what you can do is add some logic in the resolver to check if a field is not null. I found two older questions related to yours:
GraphQL query and check the returned data
GraphQL query: only include field if not null

How to pass JSON object in grpahql and strapi

When I manually write the mutation query (in graphql plugin), it's working:
mutation {
createExam(input: {
data: {
name: "myName"
desription: "ggg"
questions: [{gf: "hello"}]
time: 2
subjects: ["5c468e2d61670b25b46ccdfe"]
}
}) {
exam {
name
desription
time
}
}
}
But if I code it and pass the exact same array I get an array of the exact same object I get [null, null]
let parsedQuestion = [{gf: "hello"}];
const response = await strapi.request('POST', '/graphql', {
data: {
query: `mutation {
createExam(input: {
data: {
name: "` + examInfo.newExamName + `"
desription: "` + examInfo.newExamDescription + `"
time: ` + Number(examInfo.newExamTime) + `,
questions: `+ parsedQuestion + `,
subjects: ["` + this.state.modalSubject._id + `"]
}
}) {
exam {
name
desription
time
questions
}
}
}`
}
How can it be? Could it be a bug? I also tried with JSON.stringify but then got an error and the mutation didn't even come through
Thanks a lot in advance
Constructing a query string this way is error-prone and dangerous; it opens you up to a slew of bugs and well-known security vulnerabilities. (What if newExamName is My "super-duper" exam!!!?)
GraphQL provides variables as a better approach to pass data in. In your case since you have a complex somewhat structured object, it's probably easiest to pass the whole input in as one object (other syntaxes are possible). I would expect this to look something like:
const response = await strap.request('POST', '/graphql', {
data: {
query: `mutation CreateExam($input: CreateExamInput!) {
createExam(input: $input) {
exam { name, desription, time, questions }
}
}`,
variables: {
input: {
name: examInfo.newExamName,
desription: examInfo.newExamDescription,
time: Number(examInfo.newExamTime),
questions: [{gf: "hello"}],
subjects: [this.state.modalSubject._id]
}
}
}
});
Now the HTTP client library can take responsibility for producing well-formed JSON from your input, and you're not performing tricky string manipulation.

How do I re-do this command using the [] operator for the nesting?

I just started with RethinkDB and I love it. I have successfully got this command to work on json data:
r.db("test").table("gleif").filter({"lei:LEIRecord": {
"lei:Entity": {
"lei:HeadquartersAddress": {
"lei:City": "Toronto"
}
}
}
}).pluck({"lei:LEIRecord": {"lei:Entity": "lei:LegalName"}})
But this returns data in a json like manner. I would like to use the [] operator to simplify the query and see what type of data it returns. However, I can't seem to get the [] operator to work. I am sure you can read it, but I am filtering on the city of Toronto, but only want the LegalName returned. Thank you.
If I understand you correctly, for doc
{id: "toront",
"lei:LEIRecord": {
"lei:Entity": {
"lei:LegalName": "TorontoTest",
"lei:HeadquartersAddress": {
"lei:City": "Toronto"
}
}
}
}
by using your query you want instead of this
[{"id": "toront" ,
"lei:LEIRecord": {
"lei:Entity": {
"lei:HeadquartersAddress": {
"lei:City": "Toronto"
} ,
"lei:LegalName": "TorontoTest"
}
}
}]
get only "lei:LegalName" like this:
[{"lei:LegalName":"TorontoTest"}]
If so, then you can use map:
r.db("test").table("gleif").filter(
{"lei:LEIRecord": {
"lei:Entity": {
"lei:HeadquartersAddress": {
"lei:City": "Toronto"
}
}
}
}).map(function(doc){
return {"lei:LegalName": doc("lei:LEIRecord")("lei:Entity")("lei:LegalName")};
})
If you want to get just array of names, like this:
["TorontoTest"]
you can use this query:
r.db("test").table("gleif").filter(
{"lei:LEIRecord": {
"lei:Entity": {
"lei:HeadquartersAddress": {
"lei:City": "Toronto"
}
}
}
}).map(function(doc){
return doc("lei:LEIRecord")("lei:Entity")("lei:LegalName");
})

store and retrieve game state using HTML5 DOM storage and JSON

I am using helper functions to store and retrieve game state using HTML5 DOM storage and the JSON features built into ECMAScript5, my code is:
function saveState(state) {
window.localStorage.setItem("gameState",state);
}
function restoreState() {
var state = window.localStorage.getItem("gameState");
if (state) {
return parse(state);
} else {
return null;
}
}
but anyhow I am not getting desired output, as i am new to JSON its hard to resolve. HELP please !
Try below code:
function saveState(state) {
window.localStorage.setItem("gameState", JSON.stringify(state));
}
function restoreState() {
var state = window.localStorage.getItem("gameState");
if (state) {
return JSON.parse(state);
} else {
return null;
}
}