Powershell add column name to array data then convert it to JSON - powershell

Basically I formed an array of data based on certain conditions inside a loop and arrary data is something like this:
student1 RL123 S12 student2 RL423 S32 student6 RL166 S02 student34 RL993 P12 student99 RL923 S12
Above array data needs to be converted to JSON as below:
{
"Name" : "student1"
"RollNo" : "RL123"
"SubjectID" : "S12"
},
{
"Name" : "student2"
"RollNo" : "RL423"
"SubjectID" : "S32"
},
{
"Name" : "student6"
"RollNo" : "RL166"
"SubjectID" : "S02"
},
{
"Name" : "student34"
"RollNo" : "RL993"
"SubjectID" : "RL993"
},
{
"Name" : "student99"
"RollNo" : "RL923"
"SubjectID" : "S12"
}

If indeed your array is an array of strings (let's call it $students), you can skip the below line.
However, the way you have formatted it in your question makes it a string with space-separated items, so if that is the case, we should create a proper array from it by splitting on the whitespaces:
$students = 'student1 RL123 S12 student2 RL423 S32 student6 RL166 S02 student34 RL993 P12 student99 RL923 S12' -split '\s+'
Now just iterate over the values in the array and create objects using 3 array elements on each object:
$data = for ($i = 0; $i -lt $students.Count; $i+=3) {
[PsCustomObject]#{
Name = $students[$i]
RollNo = $students[$i + 1]
SubjectID = $students[$i + 2]
}
}
# here you convert the object array to JSON
$data | ConvertTo-Json
Output:
[
{
"Name": "student1",
"RollNo": "RL123",
"SubjectID": "S12"
},
{
"Name": "student2",
"RollNo": "RL423",
"SubjectID": "S32"
},
{
"Name": "student6",
"RollNo": "RL166",
"SubjectID": "S02"
},
{
"Name": "student34",
"RollNo": "RL993",
"SubjectID": "P12"
},
{
"Name": "student99",
"RollNo": "RL923",
"SubjectID": "S12"
}
]
the opening [ and closing ] denote that we're dealing with an array in Json syntax

Related

I am new to mongoDB need a query to delete the collections

I have two collections.
1.Equipment
db.getCollection("Equipment").find({
$and: [
{ $where: 'this._id.length <= 7' },
{ "model": "A505"}
]})
{
"_id" : "1234567",
"locationId" : "DATALOAD",
"model" : "A505",
"subscriberId" : "",
"status" : "Stock",
"headendNumber" : "4"
}
{
"_id" : "P13050I",
"locationId" : "1423110302801",
"model" : "A505",
"subscriberId" : "37",
"status" : "Stock",
"headendNumber" : "4"
}
I will get more than 100 documents (rows) Equipment collection.
2.Subscriber
db.getCollection('Subscriber').find({})
{
"_id" : "5622351",
"equipment" : [
"0018015094E6",
"1234567",
"ADFB70878422",
"M10610TCB052",
"MA1113FHQ151"
]
}
{
"_id" : "490001508063",
"equipment" : [
"17616644510288",
"P13050I",
"M91416EA4251",
"128552270280560"
]
}
In the Subscriber collection, I need to remove (get all the id from Equipment collection loop it) only the matches equipment field.
Forex from the above result, I need to remove only "1234567", and "P13050I"
Expected output.
db.getCollection('Subscriber').find({})
{
"_id" : "5622351",
"equipment" : [
"0018015094E6",
"ADFB70878422",
"M10610TCB052",
"MA1113FHQ151"
]
}
{
"_id" : "490001508063",
"equipment" : [
"17616644510288",
"M91416EA4251",
"128552270280560"
]
}
Please help me, anyone.
You can use the following to update records.
Let's find records which need to deleted and store them in array
var equipments = [];
db.getCollection("Equipment").find({ $and: [
{ $where: 'this._id.length <= 7' },
{ "model": "A505"}
]}).forEach(function(item) => {
equipments.push(item._id)
})
Now, iterate over records of the second collection and update if required.
db.getCollection('Subscriber').find({}).forEach(function(document) => {
var filtered = document.equiment.filter(id => equipments.indexOf(id) < 0);
if(filtered.length < document.equipment.length){
db.getCollection('Subscriber').update({"_id": document.id }, { $set: {'equipment': filtered}})
}
})
.filter(id => equipments.indexOf(id) < 0) will keep entries which is not present in initially populated array equipments and it will persist if there is any change.

Meteor Methods insert not working (mongodb)

I am trying to write a table with various numbers of rows and columns to a database. For this, I have a Criterion collection that saves the table headers and an Option collection that saves the table data.
The structure is like this:
for Criterion:
{
{ "_id" : "hId1", "name" : "Option Name", "tableId" : "tId1" },
{ "_id" : "hId2", "name" : "Rent", "score" : 9, "tableId" : "tId1" },
{ "_id" : "hId3", "name" : "Surface", "score" : 5, "tableId" : "tId1" },
{ "_id" : "hId4", "name" : "Price", "score" : 5, "tableId" : "tId1" },
{ "_id" : "hId5", "name" : "CPU", "score" : 5, "tableId" : "tId4" }
etc.
}
for Option:
{
{ "_id" : "id1", "score" : 5,
"hId1" : { "value" : "Apt 1" },
"hId2" : { "value" : "800 sqft", "score" : 1 },
"hId3" : { "value" : "$800", "score" : 3 },
etc.
"tableId" : "tId1"
}
{ "_id" : "id2", "score" : 5,
"hId1" : { "value" : "Apt 2" },
"hId2" : { "value" : "780 sqft", "score" : 10 },
"hId3" : { "value" : "$700", "score" : 3 },
etc.
"tableId" : "tId1"
}
etc.
}
The first row for Criterion will always have "Option Name". For the data above, the table with "tableId" = "tId1" would end up looking like this (tableId and headerId are the keys):
| Option Name | Surface | Price |
| =========== | ======== | ===== |
| Apt 1 | 800 sqft | $800 |
| Apt 2 | 780 sqft | $700 |
My code looks like this (imports/api/comparison.js):
/**
* Options are for the rows
*/
export var Option = new Mongo.Collection('option');
/**
* Criteria are the columns
*/
export var Criterion = new Mongo.Collection('criterion');
Meteor.methods({
'comparison.insertRow' (query, headerId, tableId, isFirst) {
check(query, Object);
check(headerId, String);
check(tableId, String);
check(isFirst, Boolean);
if(isFirst){
var data = {};
data._id = headerId;
data.tableId = tableId;
data.name = "Option Name";
Criterion.insert(data);
}
query._id = tableId;
Option.insert(query);
},
});
Where isFirst is a boolean expressing whether this is the first row in a table or not.
My query is constructed like this (imports/ui/Menu/DataInsert.jsx):
var query = {};
query.score = // value
// get the header separately
query[headerId] = {
value: //valueH from form
};
// Find the text field via the React ref
for (var i = 1, len = cols.length; i < len; i++) {
query[cols[i]._id] = {
value: //valueV from form,
score: //valueS from form
};
}
My files are available on the server because I am doing this in server/main.js: import '../imports/api/comparison.js';
The query gets inserted no problem into Option no problem.
Why isn't data getting inserted into Criterion (when isFirst = true)?
I did a console.log(data) and a console.log(query) and it looks like this:
whereas the data in the db looks like this:
#jordanwillis was correct above, this was happening because I was setting the _id manually on the query. I did need to set the id, but I needed to set the tableId.
So, for the record, this is what I did:
'comparison.insertRow' (query, headerId, tableId, isFirst) {
check(query, Object);
check(headerId, String);
check(tableId, String);
check(isFirst, Boolean);
if(isFirst){
var data = {};
data._id = headerId;
data.tableId = tableId;
data.name = "Option Name";
Criterion.insert(data);
}
query.tableId = tableId;
Option.insert(query);
},
And my foreign keys are tableId and headerId (which is part of query).

How to get last array element while Projection mongodb

I have following document structure (This is dummy document for understanding purpose)
{
"id" : "p1245",
"Info" : [
{
"cloth_name" : "ABC",
"cloth_type" : "C"
},
{
"cloth_name" : "PQR",
"cloth_type" : "J"
},
{
"cloth_name" : "SAM",
"cloth_type" : "T"
}
]
},
{
"id" : "p124576",
"Info" : [
{
"cloth_name" : "HTC",
"cloth_type" : "C"
}
]
}
From these document I want to project the "cloth_type", so I tried following java code
DBObject fields = new BasicDBObject("id", 1);
fields.put("ClothType","$Info.cloth_type");
DBObject project = new BasicDBObject("$project", fields);
List<DBObject> pipeline = Arrays.asList(project);
AggregationOptions aggregationOptions = AggregationOptions.builder().batchSize(100).outputMode(AggregationOptions.OutputMode.CURSOR).allowDiskUse(true).build();
Cursor cursor = collection.aggregate(pipeline, aggregationOptions);
while (cursor.hasNext())
{
System.out.println(cursor.next());
}
(I don't want to use "$unwind" here)
and get following output:
{ "id" : "p1245" , "ClothType" : [ "C" , "J" , "T"]}
{ "id" : "p124576" , "ClothType" : [ "C"]}
If there are multiple "cloth_type" for single id, then I want only the last cloth_type from this array.
I want something like, e.g. if there is array of "ClothType" [ "C", "J", "T"] then I want to project only [ "T"] i.e last element of array.
Is there any ways to achive this without using "$unwind".

Update an element in sub of sub array in mongodb

I have this data in Mongo:
{
"_id" : ObjectId("505fd43fdbed3dd93f0ae088"),
"categoryName" : "Cat 1",
"services" : [
{
"serviceName" : "Svc 1",
"input" : [
{ "quantity" : 10, "note" : "quantity = 10" },
{ "quantity" : 20, "note" : "quantity = 20" }
]
},
{
"serviceName" : "Svc 2",
"input" : [
{ "quantity" : 30, "note" : "quantity = 30" },
{ "quantity" : 40, "note" : "quantity = 40" }
]
}
]
}
Now I want to update a quantity for "Svc 1":
{ "quantity" : 10, "note" : "quantity = 10" }
Like:
{"quantity": 100, "note": "changed to 100"}
How can I do with Mongo?`
As I know, operational operator only supports for the first array, someone advised to use index of an element of the sub sub array, but the problem is that how can know that index at run time? (I'm using native C# driver of MongoDB)
Thanks in advance for your helps!
Johnny
Since you have an array within an array, there isn't any easy way to reference the nested subarray unless you know the position in the array you want to update.
So, for example, you could update the first input for 'Svc 1' with the C# equivalent of:
db.services.update(
// Criteria
{
'_id' : ObjectId("505fd43fdbed3dd93f0ae088"),
'services.serviceName' : 'Svc 1'
},
// Updates
{
$set : {
'services.$.input.0.quantity' : 100,
'services.$.input.0.note' : 'Quantity updated to 100'
}
}
)
If you don't know the position for the nested input array, you will have to fetch the matching services, iterate the input array in your application code, then $set the updated array.
Alternatively, you could modify your nested array to use an embedded document instead, eg:
{
"categoryName" : "Cat 1",
"services" : [
{
"serviceName" : "Svc 1",
"input1" : { "quantity" : 10, "note" : "quantity = 10" },
"input2" : { "quantity" : 20, "note" : "quantity = 20" }
},
]
}
Which you could then update by name, eg input1:
db.services.update(
// Criteria
{
'_id' : ObjectId("5063e80a275c457549de2362"),
'services.serviceName' : 'Svc 1'
},
// Updates
{
$set : {
'services.$.input1.quantity' : 100,
'services.$.input1.note' : 'Quantity updated to 100'
}
}
)
Since you don't know the position of the value wanted to update, first insert a new value with updated information and then remove the value wanted to update.
db.services.update(
{
'_id' : ObjectId("505fd43fdbed3dd93f0ae088"),
'services.serviceName' : 'Svc 1'
},
{
{ $addToSet: { 'services.$.input' : "new sub-Doc" }
}
)
And then remove when insert is success
db.services.update(
{
'_id' : ObjectId("505fd43fdbed3dd93f0ae088"),
'services.serviceName' : 'Svc 1'
},
{
{ $pull: { 'services.$.input' : { "quantity" : 10, "note" : "quantity = 10" } }
}
)
This is useful when index is not known and document should have sub-documents having same key like "input" in post Update an element in sub of sub array in mongodb

Is possible to query mongodb on array keys?

My table has an array indexed by a string, and i want all the records matching this string, no matter what the value is. For example get all the record wher id1 is fill :
var a = {
type: "Information",
ids: {
'id1' : '123'
'id2' : '456'
}
};
var b = {
type: "Information",
ids: {
'id1' : '789'
}
};
Is it possible to do that with mongodb and how?
You can use $exists for this:
> db.things.insert({'type': 'Information', 'ids':{'id1': 123, 'id2': 456}})
> db.things.insert({'type': 'Information', 'ids':{'id1': 746, 'id2': 456}})
> db.things.insert({'type': 'Information', 'ids':{'id2': 456, 'id3': 936}})
> db.things.find({'ids.id1': {'$exists': true}})
{ "_id" : ObjectId("4dd3c706938307861ed610dd"), "type" : "Information", "ids" : { "id1" : 123, "id2" : 456 } }
{ "_id" : ObjectId("4dd3c7a1938307861ed610de"), "type" : "Information", "ids" : { "id1" : 746, "id2" : 456 } }
Thanks to scoates in #mondodb channel, it's possible to do that with exists function : http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24exists
db.Information.find({"ids.id1":{$exists:true}});