MongoDB SSIS with $unwind - ssis

I recently started using MongoDB as a source in SSIS (using C# driver). I am very new with MongoDB and C#.
When I did not have nested documents, statements like below worked for me:
var query = Query.And(Query.Or(Query.GT("CreatedOn",maxUpdatedOnBSON), Query.GT("UpdatedOn", maxUpdatedOnBSON)),
Query.Or(Query.LT("CreatedOn", cutoffDate), Query.LT("UpdatedOn", cutoffDate)),Query.In("TestType", testTypes) );
MongoCursor<BsonDocument> toReturn = collection.Find(query);
Now, I got nested documents. I was able to create java script, and it works with MongoDB itself
db.Test.aggregate( [
{ $unwind : { path: "$Items",includeArrayIndex: "arrayIndex"} } ,
{ $match: { $and: [
{$or: [ { CreatedOn: { $gt: ISODate("2015-11-22T00:00:00Z")} }, {UpdatedOn: { $gt: ISODate("2015-11-22T00:00:00Z") } } ] },
{$or: [ { CreatedOn: { $lt: ISODate("2016-05-09T00:00:00Z")} }, {UpdatedOn: { $lt: ISODate("2016-05-09T00:00:00Z") } } ] }
] }
}] )
In C#, as I understand, I have to use aggregate instead of find but I cannot translate this code to C#. I still have selection criteria and unwind.
Can you please help?

because there is no collection template posted, i'm attaching a snippet something similar to what you would be looking for. does this help?
var builder = Builders<BsonDocument>.Filter;
//and operator can be used similar to below by using operator "&" or builder.And.
var filter = builder.Eq("state", "nj") | builder.Eq("state", "CO");
var filter2 = builder.Eq("pop", 6033) | builder.Eq("city", "nyc");
filter = builder.And(filter, filter2);
var pipeline = grades.Aggregate()
.Unwind(x => x["Items"])
.Match(filter);
var list = pipeline.ToList();
foreach (var item in list)
{
//do something
}

I got help and sharing the solution:
//Create matching criteria used in the aggregation pipeline to bring back only the specified documents based on date range
var match = new BsonDocument("$match",
new BsonDocument("$and",
new BsonArray()
.Add(new BsonDocument("$or", new BsonArray().Add(new BsonDocument("CreatedOn", new BsonDocument("$gt", maxUpdatedOnBSON))).Add(new BsonDocument("UpdatedOn", new BsonDocument("$gt", maxUpdatedOnBSON)))))
.Add(new BsonDocument("$or", new BsonArray().Add(new BsonDocument("CreatedOn", new BsonDocument("$lt", cutoffDate))).Add(new BsonDocument("UpdatedOn", new BsonDocument("$lt", cutoffDate)))))));
//create the arguments to pass to the $unwind method of the aggregation
var unwindargs = new BsonDocument("path", "$LineItems");
unwindargs.Add("includeArrayIndex", "arrayIndex");
//create the unwind stage and add the arguments
var unwind = new BsonDocument("$unwind", unwindargs);
//create a new pipeline and gather the results
var pipeline = new[] { match, unwind };
var mongoArgs = new AggregateArgs { Pipeline = pipeline };
var toReturn = collection.Aggregate(mongoArgs).ToList();

Related

Function inside a Function not calling in React Native

I am new to react-native and calling a function inside a fucntion.
I have done as below so far :
Step 1 : Created a function _snapshotToArray to convert the firebase snapshot to Arrray.
_snapshotToArray(snapshot) {
var returnArr = [];
snapshot.forEach(function(childSnapshot) {
var item = childSnapshot.val();
item.key = childSnapshot.key;
returnArr.push(item);
});
return returnArr;
}
Step 2 : Created another function as below and calling _snapshotToArray inside it.
_readUserDataFromFirebaseConsole() {//once and on
firebase.database().ref('Users/').on('value', function (snapshot) {
console.log(this._snapshotToArray(snapshot));
Toast.show(this._snapshotToArray(snapshot),Toast.LONG);
});
}
Talking about this call :
console.log(this._snapshotToArray(snapshot));
When I press CTRL+CLick, it not letting me to navigate to body of the fuction _snapshotToArray.
In Device am getting below error :
_snapshotToArray is not defined
What might be the issue ?
I'm not at my PC right now, so I cannot test it, but from looking at your code, you need to use a different function notation to allow the varibale access of/from parent methods and parent class.
_snapshotToArray = snapshot => {
var returnArr = [];
snapshot.forEach(function(childSnapshot) {
var item = childSnapshot.val();
item.key = childSnapshot.key;
returnArr.push(item);
});
return returnArr;
}
and
_readUserDataFromFirebaseConsole = () => {
firebase.database().ref('Users/').on('value', snapshot => {
console.log(this._snapshotToArray(snapshot));
Toast.show(this._snapshotToArray(snapshot),Toast.LONG);
});
}

Google Slides: newly inserted table not found

I´m wondering what is going on. I have two functions which both are working good when called one after one:
function createTable() {
var slidesPage = SlidesApp.openById('1QWRV4eQzGNNBz4SkR3WPurTL3O60oGYxQpBu63KrUoI').getSlides()[0];
var table = slidesPage.insertTable(7, 4);
}
function changeColumnWidth() {
var slidesPage = SlidesApp.openById('1QWRV4eQzGNNBz4SkR3WPurTL3O60oGYxQpBu63KrUoI').getSlides()[0];
var tableId = slidesPage.getTables()[0].getObjectId();
var requests = [{
updateTableColumnProperties: {
objectId: tableId,
"columnIndices": [ 1, 3],
"tableColumnProperties": {
"columnWidth": {
"magnitude": 80,
"unit": "PT"
}
},
"fields": "columnWidth"
}
}];
var createSlideResponse = Slides.Presentations.batchUpdate({
requests: requests
}, '1QWRV4eQzGNNBz4SkR3WPurTL3O60oGYxQpBu63KrUoI');
}
But trying to combine these two functions like:
function combined() {
createTable();
changeColumnWidth();
}
I´m getting Error:
Invalid requests[0].updateTableColumnProperties: The object (SLIDES_API456304911_0) could not be found.
Wondering if the insertTable method is asynchronous and therefore the created table is not ready?
Thanks for any help.
How about this modification? Please think of this as one of several workarounds. In my workaround, I used saveAndClose() for your situation. Using this, I thought to separate the process of SlidesApp and Slides API.
Modification points :
Save and close the slide using saveAndClose() after the table was inserted.
Return an object ID of inserted table to use at changeColumnWidth().
At changeColumnWidth(), the table is modified by Slides API using the received object ID.
Modified script :
function combined() {
var tableId = createTable(); // Modified
changeColumnWidth(tableId); // Modified
}
function createTable() {
var slide = SlidesApp.openById('1QWRV4eQzGNNBz4SkR3WPurTL3O60oGYxQpBu63KrUoI'); // Modified
var slidesPage = slide.getSlides()[9]; // Modified
var table = slidesPage.insertTable(7, 4);
slide.saveAndClose(); // Added
return table.getObjectId();
}
function changeColumnWidth(tableId) { // Modified
// var slidesPage = SlidesApp.openById('1QWRV4eQzGNNBz4SkR3WPurTL3O60oGYxQpBu63KrUoI').getSlides()[0]; // This line is not used.
// var tableId = slidesPage.getTables()[0].getObjectId(); // This line is not used because slidesPage.getTables().length becomes 0.
var requests = [{
updateTableColumnProperties: {
objectId: tableId,
"columnIndices": [ 1, 3],
"tableColumnProperties": {
"columnWidth": {
"magnitude": 80,
"unit": "PT"
}
},
"fields": "columnWidth"
}
}];
var createSlideResponse = Slides.Presentations.batchUpdate({
requests: requests
}, '1QWRV4eQzGNNBz4SkR3WPurTL3O60oGYxQpBu63KrUoI');
}
Note :
For the slide which is saved and closed by saveAndClose(), when the slide is reopened, the inserted table cannot be retrieved. When the table is tried to be retrieved using getTables() again, the length becomes 0. But at Slides API, the object ID of table can be retrieved. So I thought that the issue might be able to be solved by returning the object ID of table after the table was inserted.
But I couldn't understand about the reason that the values retrieved by getTables() from the reopened Slide become "0" yet. I'm sorry.
Reference :
saveAndClose()
If this workaround was not what you want, I'm sorry.
To achieve your goal - create a table with a specified layout and specific column sizes in one function - you should use the Slides API for the entire task. The Slides API lets you both create and modify the same element in the same batch request, if you provided a unique object ID for it. Otherwise, you have to first create the element, then send the modification request using the objectId found in the response to the first request. This second approach is essentially the behavior you were experiencing when the function calls were done separately.
There are restrictions on user-supplied IDs, naturally:
objectId string: A user-supplied object ID.If you specify an ID, it must be unique among all pages and page elements in the presentation. The ID must start with an alphanumeric character or an underscore (matches regex [a-zA-Z0-9_] ); remaining characters may include those as well as a hyphen or colon (matches regex [a-zA-Z0-9_-:] ). The length of the ID must not be less than 5 or greater than 50.If you don't specify an ID, a unique one is generated.
Given that hyphens are allowed, we can use the Utilites.getUuid() method to help supply our own unique object IDs.
When mixing SlidesApp and Slides, it is very likely that internal Google optimizations (e.g. write-caching) change the operation order. By restricting to a single service for related task operations, we can ensure that the objects we need are available when needed.
This example uses two methods that make Request objects for batchUpdate and ultimately creates a presentation, adds a blank slide, adds a table and modifies it, and then creates another blank slide.
function makeCreateTableRequest_(slideId, rows, columns, shouldSupplyID) {
const tablerq = {
rows: rows,
columns: columns,
elementProperties: {
pageObjectId: slideId,
/** size: {
height: {...},
width: {...}
},
transform: { ... } */
}
};
// If asked to use a custom ID (e.g. also going to modify this table), use a unique one.
if (shouldSupplyID)
tablerq.objectId = ("table" + Utilities.getUuid()).slice(0, 50);
return {createTable: tablerq};
}
function makeModifyTableColumnPropsRequest_(tableId, newWidthDimension, indicesArray) {
const rq = {
objectId: tableId,
fields: "columnWidth" // There are no other fields for this request as of 2018-07
};
if (newWidthDimension && newWidthDimension.magnitude !== undefined && newWidthDimension.unit)
rq.tableColumnProperties = { columnWidth: newWidthDimension };
if (indicesArray && indicesArray.length)
rq.columnIndices = indicesArray;
return {updateTableColumnProperties: rq};
}
function createPresentation_() {
const newPres = { title: "API-created Presentation" };
// Presentations are huge... limit the metadata sent back to us.
const fields = "presentationId,pageSize,title"
+ ",slides(objectId,pageType,pageElements(objectId,size,title,description))"
+ ",masters(objectId,pageType,pageElements(objectId,size,title,description))"
+ ",layouts(objectId,pageType,pageElements(objectId,size,title,description))";
const createdMetadata = Slides.Presentations.create(newPres, {fields: fields});
console.log({message:"Created a Presentation", response: createdMetadata});
return createdMetadata;
}
function addSlide_(pId) {
const response = Slides.Presentations.batchUpdate({ requests: [{ createSlide: {} }] }, pId);
return response.replies[0].createSlide.objectId;
}
function foo() {
const pres = createPresentation_();
const newSlideId = addSlide_(pres.presentationId);
// Get requests to add and to modify tables.
const openingTableRq = makeCreateTableRequest_(pres.slides[0].objectId, 2, 4);
const newTableRq = makeCreateTableRequest_(newSlideId, 7, 4, true);
const changeWidthRq = makeModifyTableColumnPropsRequest_(newTableRq.createTable.objectId, {magnitude: 80, unit: "PT"}, [0]);
// Add and update the desired table, then create a new slide.
var response = Slides.Presentations.batchUpdate({
requests: [
openingTableRq, // will have reply
newTableRq, // will have reply
changeWidthRq, // no reply
{ createSlide: {} } // will have reply
]
}, pres.presentationId);
console.log({message: "Performed updates to the created presentation", response: response});
}

SAPUI5 get single property from JSON-Model

I am currently trying to figure out how I can retrieve a single value from a sap.ui.model.json.JSONModel
in my main view:
var gConfigModel = new sap.ui.model.json.JSONModel();
var getConfigCallback = function(config) {
gConfigModel.setData(config);
};
oController.getConfiguration(getConfigCallback);
console.log(gConfigModel);
in my controller:
getConfiguration : function(callback) {
var sServiceUrl = "/sap/opu/odata/sap/xxx/ConfigurationSet('Initialize')";
var config = {};
callback(config);
$.getJSON(sServiceUrl).done(function(data) {
config = data.d;
callback(config);
});
},
In my console.log statement I can see that the data was successfully passed from the backend and successfully set to the JSON model. My requirement is to store the value of attribute Editable in a single variable.
I already tried gConfigModel.getProperty('/'), didnt work. tried to access gConfigModel.oData was undefined .. How can I store it in a single value?
Solution Comment: If you catch data from a backend, you have to take care how long it takes. data can be available later then expected, in my case I added 1s timeout, afterwards I can access the property easily
setTimeout(function() {
console.log(gConfigModel.getProperty('/Editable'));
}, 1000);
I wouldn't advise using the model's getData() method since it is deprecated.
A much better solution is to use gConfigModel.getProperty("/Editable")
(I'm using the root slash here since your property resides in the root of your model)
In the same way, you can also set your data:
gConfigModel.setProperty("/Editable", <your new value>) instead
First of all, thanks for the effort to find solutions of our Problems! (at least, those regarding It stuff.. :) )
I've found a solution which I think is a little bit more save because the timeout is maybe somewhat arbitrary - it would depend on the machine or the amount of data that is to be fetched?
Therefore, I am using an attachRequestCompleted function:
with sUrl_2="path-to-my-service";
var oModel_2 = new sap.ui.model.json.JSONModel(sUrl_2);
oModel_2.attachRequestCompleted(function(data) {
//now, i can access the data stored in the oModel_2, either by getProperty, or by DOM: oModel_2.oData.d.Vendor
gv_selLieferant = oModel_2.getProperty("/d/Vendor");
gv_selEinkOrg = oModel_2.getProperty("/d/PurchOrg");
gv_selEinKGru = oModel_2.getProperty("/d/PurGroup");
});
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-theme="sap_bluecrystal" data-sap-ui-libs="sap.m"></script>
<script>
function getConfiguration(callback) {
var sServiceUrl = "/sap/opu/odata/sap/xxx/ConfigurationSet('Initialize')";
var config = {};
var data = {
"d": {
"_metadata": "",
"Backup01": "01",
"Editable": "True"
}
};
setTimeout((function() {
config = data;
callback(config);
})(), 2000);
};
var gConfigModel = new sap.ui.model.json.JSONModel();
var getConfigCallback = function(config) {
gConfigModel.setData(config);
alert(gConfigModel.getProperty("/d/Editable"));
};
getConfiguration(getConfigCallback);
</script>

How to create an object of specific type from JSON in Parse

I have a Cloud Code script that pulls some JSON from a service. That JSON includes an array of objects. I want to save those to Parse, but using a specific Parse class. How can I do it?
Here's my code.
Parse.Cloud.httpRequest({
url: 'http://myservicehost.com',
headers: {
'Authorization': 'XXX'
},
success: function(httpResponse) {
console.log("Success!");
var json = JSON.parse(httpResponse.text);
var recipes = json.results;
for(int i=0; i<recipes.length; i++) {
var Recipe = Parse.Object.extend("Recipe");
var recipeFromJSON = recipes[i];
// how do i save recipeFromJSON into Recipe without setting all the fields one by one?
}
}
});
I think I got it working. You need to set the className property in the JSON data object to your class name. (Found it in the source code) But I did only try this on the client side though.
for(int i=0; i<recipes.length; i++) {
var recipeFromJSON = recipes[i];
recipeFromJSON.className = "Recipe";
var recipeParseObject = Parse.Object.fromJSON(recipeFromJSON);
// do stuff with recipeParseObject
}
Example from this page https://parse.com/docs/js/guide
var GameScore = Parse.Object.extend("GameScore");
var gameScore = new GameScore();
gameScore.save({
score: 1337,
playerName: "Sean Plott",
cheatMode: false
}, {
success: function(gameScore) {
// The object was saved successfully.
},
error: function(gameScore, error) {
// The save failed.
// error is a Parse.Error with an error code and message.
}
});
IHMO this question is not a duplicate of How to use Parse.Object fromJSON? [duplicate]
In this question the JSON has not been generated by the Parse.Object.toJSON function itself, but comes from another service.
const object = new Parse.Object('MyClass')
const asJson = object.toJSON();
// asJson.className = 'MyClass';
Parse.Object.fromJSON(asJson);
// Without L3 this results into:
// Error: Cannot create an object without a className
// It makes no sense (to me) why the Parse.Object.toJSON is not reversible

How to retrieve the data from database using Indexed DB

I have an existed database. I'm trying to retrieve the data from database using indexedDB but i'm unable to get the data from database.
var data = [];
// creating or opening the database
var db;
var request = window.indexedDB.open("database");
request.onerror = function(event) {
console.log("error: ");
};
request.onsuccess = function(event) {
db = request.result;
console.log("success: "+ db);
};
request.onupgradeneeded = function(event) {
var db = event.target.result;
var objectStore = db.createObjectStore("Subject", {keyPath: "id"});
for (var i in data) {
objectStore.add(data[i]);
}
}
function readAll() {
var objectStore = db.transaction("Subject").objectStore("Subject");
console.log(objectStore);
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
alert("Name for id " + cursor.key + " is " + cursor.value.Subject);
cursor.continue();
}
else {
alert("No more entries!");
}
};
}
Thanks in Advance.
You're pretty close.
var data = [];
I'll presume that you actually have some data somewhere, and that it indeed has an id attribute since you're specifying that as your index key e.g.
var data = [{id: 'foo' }, { id: 'bar' } ];
Now here:
var objectStore = db.createObjectStore("Subject", {keyPath: "id"});
for (var i in data) {
objectStore.add(data[i]);
}
(Careful with for..in and arrays)
I don't think you're actually adding any data here, which is one reason why you can't read it. To add data to an object store, try to first create a read/write transaction first and then get your reference to the object store and add your object.
var trans = db.transaction(["Subject"], "readwrite").objectStore("Subject");
Note the usage of an array as the first argument to transaction() and "readwrite" as the second param. (Some examples use the IDBTransaction.READ_WRITE constant but this doesn't seem to work with recent versions of Webkit.)
var objectStore = db.transaction("Subject").objectStore("Subject");
Try this instead:
var trans = db.transaction( [ "Subject" ] );
, objectStore = trans.objectStore( "Subject" );
objectStore.openCursor( IDBKeyRange.lowerBound(0) ).onsuccess = function(event) {..}
I did encountered the same error once. it occurs because at times the onSuccess is executed even before the result data is returned. So you should check if result data is empty.
To solve the issue try using oncomplete instead of onSuccess and also use Jquery indexedDB plugin. The plugin requires certin code changes but has more consistent implementation of indexedDB.
See http://nparashuram.com/jquery-indexeddb/