How would I search a JSON array in nodejs - node.js

I've got an JSON Array listed below:
{
"jsonrpc": "2.0",
"id": 1,
"result": [
{
"_id": "6125496b64ec43ef984a48ad",
"imdb_id": "tt10872600",
"name": "Spider-Man: No Way Home",
"type": "movie",
"year": "2021"
},
{
"_id": "61f3e33b64ec43ef98553e07",
"imdb_id": "tt13634480",
"name": "The Ice Age Adventures of Buck Wild",
"type": "movie",
"year": "2022"
},
{
"_id": "5c4f384dd582b25756275494",
"imdb_id": "tt9032400",
"name": "Eternals",
"type": "movie",
"year": "2021"
}
]
}
I'm wanting to make a function to search through this array by imdb_id or name (not both).
How would I go about doing this?
My poor attempt:
const json = require('./test.json');
function Search(file){
for (let i = 0; i < file.length; i++) {
console.log(file[i].results[i].imdb_id);
}
}
Search(json);

At simplest, you could leverage the inbuilt filtering function, something like this
const idOrNameEquals = searchStr => item => item.imdb_id === searchStr || item.name === searchStr
const json = require('./test.json')
const foundItems = json.result.filter(idOrNameEquals('Eternals'))

try using filter
function SearchJson(json, imdb_id, name){
return json.result.filter( function(item) {
return imdb_id==null? item.name == name : item.imdb_id==imdb_id
});
};
test
var result= SearchJson(json,null, "Eternals");
result
[
{
"_id": "5c4f384dd582b25756275494",
"imdb_id": "tt9032400",
"name": "Eternals",
"type": "movie",
"year": "2021"
}
]

Related

Duplicate a document DB using MongoDB Model

I want to duplicate a document from MongoDB Model in NodeJS, below is the structure
{
"_id": "62fe22f4b3c0fabfd1222d40", // this needs to be replaced in duplicated document
"id": 1, // this is auto increment field, needs to be generated new auto increment field
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
I did refer this Duplicate a document in MongoDB using a new _id post, however I am not sure of resetting auto increment id
Assuming you use a NodeJS application you could do the following. Of course, if your id auto-increment is specified.:
const { _id, id, __v, ...newMyObj } = await MyModel.findOne({ id }).lean();
await MyModel.create(newMyObj);
I was able to fix the solution with below
const myDoc = await myModel.findOne({ id }).exec();
if (myDoc) {
const myDocObj = myDoc.toObject();
delete myDocObj._id;
delete myDocObj.id;
... continue deleting more unwanted props
return new myModel(myDocObj);
}
return null;

Merge multiple object arrays and removing duplicates based on optional property

Say if there are arrays like:
const arr1 = [
{ "id": "1", "type": "sales" },
{ "id": "2", "type": "finance" }
]
const arr2 = [
{ "type": "sales" },
{ "id": "2", "type": "finance" }
]
const arr3 = [
{ "id": "1", "type": "sales" },
{ "type": "sales" },
{ "type": "finance" }
]
As you can see, id is optional. I need to merge arrays in such way that uniqueness should be based on id if present, else entire rest of the object.
ex. here merged array would be:
[
{ "id": "1", "type": "sales" },
{ "type": "sales" },
{ "id": "2", "type": "finance" },
{ "type": "finance" }
]
loadash has .unionBy but optional uniqueness doesn't work.
const result = _.unionBy(arr1, arr2, arr3, 'id')
Probably I have to iterate through each, but I was wondering if there is any simpler alternative for this.
Instead of _.unionBy you can use _.unionWith which accepts a custom comparator. The logic for comparison is:
Compare by ID if both items have an ID.
Compare by type if both items do not have an ID.
Consider them different if one has an ID the other not.
const arr1 = [
{ "id": "1", "type": "sales" },
{ "id": "2", "type": "finance" }
]
const arr2 = [
{ "type": "sales" },
{ "id": "2", "type": "finance" }
]
const arr3 = [
{ "id": "1", "type": "sales" },
{ "type": "sales" },
{ "type": "finance" }
]
const result = _.unionWith(arr1, arr2, arr3, (item1, item2) => {
const item1HasId = _.has(item1, "id");
const item2HasId = _.has(item2, "id");
if (item1HasId && item2HasId) //if both have ID...
return item1.id === item2.id; // ...compare by ID
if (!item1HasId && !item2HasId) //if neither has ID...
return item1.type === item2.type; // ...compare by type
return false; // otherwise not equal
});
console.log(result);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js"></script>

Add response to each item for loop in node.js and postgres

I have an array of schools like this:
{
"schools": [
{
"name": "S1",
"id": 1
},
{
"name": "S2",
"id": 2
},
{
"name": "S3",
"id": 3
}
]
}
and each school has schedule. To Get that I iterate the schools array in a promise and when I get the response I get an array like this
{
"schools": [
{
"name": "S1",
"id": 1
},
{
"name": "S2",
"id": 2
},
{
"name": "S3",
"id": 3
}
],
"schedules": [
[],
[
{
"id_schedule": 58,
"hour1": "13:00:00",
"hour2": "20:00:00",
"id_schools_schedule": 2
}
],
[
{
"id_schedule": 59,
"hour1": "06:30:00",
"hour2": "22:30:00",
"id_schools_schedule": 3
}
]
]
}
I want to know. how to asign the response of each item?
this is my code
for (var i =0; i < datosRes.schools.length; i++){
array_horarios.push(ObtSchedule(datosRes.schools, i))
}
Promise.all(array_horarios).then(response => {
datosRes.horarios = response;
eq.local = data;
}).catch(err => {
return res.json(200,{"datos":datosRes});
})
function ObtHorario(schools, i){
return new Promise(function(resolve, reject){
var id_school = schools[i].id;
Mod_Schedule.obtSchedule(id_school,function(error, data){
if(error || data.error){
errorDB = {"error_log": error, "error_data": data.error};
reject(errorDB)
}else{
resolve(data)
}
})
})
}
What I am doing wrong?
I get the response but only I want to add to each item of schools the schedules
Thanks in advance
First thing first:
You can send ONE response to ONE request. So your question to send multiple responses is invalid.
Here's what you can do, you can get the array of schools with their schedules.
If you are using MongoDB, here's what you can do:
Using Aggregate query:
db.schools.aggregate([
{
$match: {} // Your condition to match schools here
},
{
$lookup: {
from:"schedules",
localField: id,
foreignField: id_schools_schedule,
as: "schedulesData"
}
},
]);
Here, you will get data something like:
[
{
"name": "S1",
"id": 1,
"schedulesData": []
},
{
"name": "S2",
"id": 2,
"schedulesData": [{
"id_schedule": 58,
"hour1": "13:00:00",
"hour2": "20:00:00",
"id_schools_schedule": 2
}]
},
{
"name": "S3",
"id": 3,
"schedulesData": [
{
"id_schedule": 59,
"hour1": "06:30:00",
"hour2": "22:30:00",
"id_schools_schedule": 3
}
]
}
]

Mongoose Querying Sub-Document Properties

I am trying to expose this functionality through a WEB API. The way it is set up in this code is that someone does a GET on URL providing a querystring along with it in the form of:
?field=value&anotherfield.subproperty=value
But I can't seem to get querying based on sub-document properties to work. Below you will find my barebones code, record I'm trying to receive and both of my test cases.
Code:
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var config = require('../config');
var User = require('../models/user');
var functions = require('../functions');
router.get('/', function(req,res,next) {
//Check Permissions associated with UID *TODO
var parameters = req.query;
console.log(parameters);
User.find(parameters, function(err, users) {
if (err)
{
json = functions.generateOperationOutcome("exception","error",err,"exception");
res.status(500);
res.json(json);
}
else
{
//Check for blank result
if (users.length === 0)
{
json = functions.generateOperationOutcome("not-found","warning","Non-Existent Resource","warning");
res.status(404);
res.json(json);
}
else {
res.status(200);
res.json(users);
}
}
});
});
Record:
{
"_id": "5871d2e814946a941d8611fb",
"resourceType": "testResource",
"link": [],
"communication": [],
"animal": {
"genderStatus": {
"coding": []
},
"breed": {
"coding": []
},
"species": {
"coding": []
}
},
"contact": [],
"photo": [],
"maritalStatus": {
"coding": []
},
"address": [],
"gender": "unknown",
"telecom": [
{
"system": "phone",
"value": "2019196553",
"use": "home"
}
],
"name": {
"suffix": [],
"prefix": [],
"given": [],
"family": []
},
"identifier": [
{
"use": "official",
"type": {
"coding": {
"system": "kylec laptop",
"version": "0.01",
"code": "UDI",
"display": "Universal Device Identifier",
"userSelected": false
},
"text": "test"
},
"system": "test system",
"value": "test value",
"assigner": {
"reference": "test assigner reference"
},
"period": {
"start": "1992-12-31T09:59:59+00:00"
}
}
]
}
Successful Query:
GET http://{{LOCAL}}/api/user?resourceType=testResource
Returns this one model from MongoDB.
Unsuccessful Query (no documents matching query found):
GET http://{{LOCAL}}/api/user?telecom.system=phone
Returns no models back and results in a 404.
You are not properly using dot-notation, as the property you're seeking is within an array:
"telecom": [
{
"system": "phone",
"value": "2019196553",
"use": "home"
}
]
Querying array content typically would require you to do a join against the array (for DocumentDB queries), and not a simple find().
If you wanted the ability to use dot-notation here, you'd need to create a subdocument, like:
"telecom": {
"system": "phone",
"value": "2019196553",
"use": "home"
}
At this point, you'd be able to address properties such as telecom.system, telecom.value, and telecom.use.

CouchDB's Linked Documents in a View

I'm having a hard time getting my head around CouchDB's linked documents feature.
I have two types of data being stored in a single CouchDB database:
{
"id":"1",
"type": "track",
"title": "Bohemian Rhapsody"
}
{
"id":"2",
"type": "artist",
"name": "Queen",
"tracks": ["1"]
}
I'm under the impression that I can write a view like the one below and get the following documents emited:
{
"id":"2",
"type": "artist",
"name": "Queen",
"tracks": [
{
"id":"1",
"type": "track",
"title": "Bohemian Rhapsody"
}
]
}
I've been trying this view, but it's not working the way I'm expecting:
function(doc) {
if(doc.type == 'artist') {
var tracks = [];
for(var i = 0; i < doc.tracks.length; i++) {
tracks.push({_id:doc.tracks[i]});
}
newdoc = eval(uneval(doc));
newdoc.tracks = tracks;
emit(doc._id,newdoc);
}
}
example here: http://jphastings.iriscouch.com/_utils/database.html?music/_design/test/_view/linked
This isn't returning what I'd hope - do you have any suggestions? Thanks
Okay I finally understand what you are trying to do.Yes this is possible.Here is how.
You have 2 documents
{
"_id":"anyvalue",
"type": "track",
"title": "Bohemian Rhapsody"
}
{
"_id":"2",
"type": "artist",
"name": "Queen",
"tracks": ["anyvalue"]
}
What you were doing wrong was not having quotes around the value of tracks(the item in the array).
2)The reference id must be _id for this to work.The difference is worth noting since you can have id field but only _id are used to identify documents.
For the result you want this view would suffice
function(doc) {
if (doc.type === 'artist') {
for (var i in doc.tracks) {
var id = doc.tracks[i];
emit(id, { _id: id });
}
}
}
What you want to be doing is use an emit function inside the for loop to emit the id field of the 'track' of every artist.
Then you want to query couch db view with the include_docs=true parameter.Here is the final result for the database that you created on iris couch.
http://jphastings.iriscouch.com/music/_design/test/_view/nested?reduce=false&include_docs=true
{
"total_rows": 3,
"offset": 0,
"rows": [
{
"id": "0b86008d8490abf0b7e4f15f0c6a50a7",
"key": "0b86008d8490abf0b7e4f15f0c6a463b",
"value": {
"_id": "0b86008d8490abf0b7e4f15f0c6a463b"
},
"doc": {
"_id": "0b86008d8490abf0b7e4f15f0c6a463b",
"_rev": "3-7e4ba3bfedd29a07898125c09dd7262e",
"type": "track",
"title": "Boheniam Rhapsody"
}
},
{
"id": "0b86008d8490abf0b7e4f15f0c6a50a7",
"key": "0b86008d8490abf0b7e4f15f0c6a5ae2",
"value": {
"_id": "0b86008d8490abf0b7e4f15f0c6a5ae2"
},
"doc": {
"_id": "0b86008d8490abf0b7e4f15f0c6a5ae2",
"_rev": "2-b3989dd37ef4d8ed58516835900b549e",
"type": "track",
"title": "Another one bites the dust"
}
},
{
"id": "0b86008d8490abf0b7e4f15f0c6a695e",
"key": "0b86008d8490abf0b7e4f15f0c6a6353",
"value": {
"_id": "0b86008d8490abf0b7e4f15f0c6a6353"
},
"doc": {
"_id": "0b86008d8490abf0b7e4f15f0c6a6353",
"_rev": "2-0383f18c198b813943615d2bf59c212a",
"type": "track",
"title": "Stripper Vicar"
}
}
]
}
Jason explains it wonderfully in this post
Best way to do one-to-many "JOIN" in CouchDB
this link is also helpful for entity relationships in couch db
http://wiki.apache.org/couchdb/EntityRelationship

Resources