So I have a dynamic query and I'm wondering is there a way to trace what statement its exactly executing for tracing purposes?
r.db('appname').table('food')
.hasFields({'fruits': {'secondary': true}})
.filter(function(row) {
var userDefaultCondition = [];
_.forEach(params.userDefault, function(service) {
userDefaultCondition.push(row('fruits')('favorite').match(service));
});
var userRequestedCondition = [];
_.forEach(params.userRequested, function(service) {
userRequestedCondition.push(row('fruits')('favorite').match(service));
});
return r.and(
row('inventory')('status').match('AVAILABLE')
).and(
r.or(
userDefaultCondition
).and(
r.or(
userRequestedCondition
)
)
)
})
I figured it out, to trace query, you need to assign it to a variable and apply toString().
var query = r.db('appname').table('food')
.hasFields({'fruits': {'secondary': true}})
.filter(function(row) {
var userDefaultCondition = [];
_.forEach(params.userDefault, function(service) {
userDefaultCondition.push(row('fruits')('favorite').match(service));
});
var userRequestedCondition = [];
_.forEach(params.userRequested, function(service) {
userRequestedCondition.push(row('fruits')('favorite').match(service));
});
return r.and(
row('inventory')('status').match('AVAILABLE')
).and(
r.or(
userDefaultCondition
).and(
r.or(
userRequestedCondition
)
)
)
});
//trace query
console.log(query.toString());
//run query
query.run()
.then(function(res) {
console.log(res);
}).error(function(err){
console.log(err);
});
Thanks to: http://www.ronniesan.com/viewing-a-dynamically-generated-reql-query/
P.S This query is not yet working as expected as I'm still figuring out how to do dynamic rethinkdb queries
Related
Can someone please explain to me why i'm getting this warning Warning: a promise was created in a handler but was not returned from it when I execute the following code:
cache['deviceSlave'].getBySystemId(systemId).then(function(slavesMapping) {
// do other stuff
}).catch(function(err) {
// throw error
});
Here is the rest of the code:
var Promise = require('bluebird');
var _ = require('lodash');
var Redis = require('ioredis');
var config = require('/libs/config');
var redis = new Redis({
port: config.get('redis:port'),
host: config.get('redis:host'),
password: config.get('redis:key'),
db: 0
});
var self = this;
module.exports.getBySystemId = function(systemId) {
return new Promise(function(resolve, reject) {
var systemIds = [systemId];
self.getBySystemIds(systemIds).then(function(result) {
return resolve(_.values(result)[0]);
}).catch(function(err) {
return reject(err);
});
});
};
module.exports.getBySystemIds = function(systemIds) {
return new Promise(function(resolve, reject) {
var pipeline = redis.pipeline();
_.each(systemIds, function(systemId) {
var cacheKey = 'device_slaves:' + systemId.replace(/:/g, '');
// get through pipeline for fast retrieval
pipeline.get(cacheKey);
});
pipeline.exec(function(err, results) {
if (err) return reject(err);
else {
var mapping = {};
_.each(systemIds, function(systemId, index) {
var key = systemId;
var slaves = JSON.parse(results[index][1]);
mapping[key] = slaves;
});
return resolve(mapping);
}
});
});
};
I'm using the following libraries: ioredis & bluebird.
The code executes fine and everything just works good! I just dont like the fact I get an warning which I can not solve!
Bluebird is warning you against explicit construction here. Here is how you should write the above code:
module.exports.getBySystemId = function(systemId) {
return self.getBySystemIds([systemId]).then(result => _.values(result)[0]);
};
There is no need to wrap the promise - as promises chain :)
I am trying to import my class (2500 records) from Parse.com into an Algolia index. There is a limit of 100 records by default which obviously is not working for me. Even if I use query.limit = 1000;
How can the below code be used to import my whole class?
Parse.Cloud.define("createIndex", function(request, response) {
var algoliasearch = require('cloud/algoliasearch.parse.js');
var client = algoliasearch('9PsdfsdWVU7', '3b24e897bfb4esdfsdfsdf209e25c28');
var index = client.initIndex('exercises');
console.log("running");
var objectsToIndex = [];
//Create a new query for Contacts
var query = new Parse.Query('Exercises');
query.limit = 1000;
// Find all items
query.find({
success: function(exercises) {
// prepare objects to index from contacts
objectsToIndex = exercises.map(function(exercise) {
// convert to regular key/value JavaScript object
exercise = exercise.toJSON();
// Specify Algolia's objectID with the Parse.Object unique ID
exercise.objectID = exercise.objectId;
return exercise;
});
// Add or update new objects
index.saveObjects(objectsToIndex, function(err, content) {
if (err) {
throw err;
}
console.log('Parse<>Algolia import done');
});
response.success("worked");
},
error: function(err) {
response.error("failed");
throw err;
}
});
});
Parse.com has a find limit, and all other limitations when you want to "get all the objects", you can find more information here: https://parse.com/docs/js/guide#performance-limits-and-other-considerations
For your current issue you could do this:
Parse.Cloud.define("createIndex", function(request, response) {
var algoliasearch = require('cloud/algoliasearch.parse.js');
var client = algoliasearch('9PsdfsdWVU7', '3b24e897bfb4esdfsdfsdf209e25c28');
var index = client.initIndex('exercises');
console.log("running");
//Create a new query for Contacts
var Exercises = Parse.Object.extend('Exercises');
var query = new Parse.Query(Exercises);
var skip = -1000;
var limit = 1000;
saveItems();
function saveItems() {
skip += limit;
query.skip(skip + limit);
query.limit(limit);
query.find({success: sucess, error: error});
}
function sucess(exercices) {
if (exercices.length === 0) {
response.success("finished");
return;
}
exercises = exercises.map(function(exercise) {
// convert to regular key/value JavaScript object
exercise = exercise.toJSON();
// Specify Algolia's objectID with the Parse.Object unique ID
exercise.objectID = exercise.objectId;
return exercise;
});
index.saveObjects(exercises, function(err) {
if (err) {
throw err;
}
console.log('Parse<>Algolia import done');
response.success("worked");
saveItems();
});
}
function error() {
response.error("failed");
throw err;
}
});
It seems I have an issue with async on promise. I have tested with sails-mysql, sails-mongo, sails-postgres version 0.10-rc-XX and the problem is happen. But when I use sails-disk, there's no problem. Look my comment below
var storeInvoiceDetail = function( detail ) {
return function( cb ) {
cb(null, detail);
};
}
var getPreviousDetail = ['storeInvoiceDetail', function( cb, results ) {
var invoiceDetail = results.storeInvoiceDetail;
PreviousDetail
.findOne({
invoice: invoiceDetail.invoice,
product: invoiceDetail.product.id
})
.sort('createdAt desc')
.exec(cb);
}];
var createPreviousDetail = ['storeInvoiceDetail', function( cb, results ) {
var invoiceDetail = results.storeInvoiceDetail;
PreviousDetail
.create({
invoice: invoiceDetail.invoice,
product: invoiceDetail.product.id,
quantity: invoiceDetail.quantity
})
.exec(cb);
}];
var getStockDifference = ['storeInvoiceDetail', 'getPreviousDetail', function( cb, results ) {
var difference = results.storeInvoiceDetail.quantity - results.getPreviousDetail.quantity;
cb(null, difference);
}];
// see here
var updateProductStock = ['getPreviousDetail', 'getStockDifference', function( cb, results ) {
Product
.findOne(results.getPreviousDetail.product)
.then(function(product) {
// imagine the value of 'results.getStockDifference' is 5
product.stock += results.getStockDifference;
product.save();
// when I do log, the output is: 5, but this value is not updated to database
// It seems 'product.save()' at above is not called
// maybe this code have issues with 'async' & 'promise'
// anybody know how to correct this?
console.log(product.stock);
cb(null, product.stock);
});
}];
exports.updateProductStock = function (details) {
var beforeModifyProductStock = {};
async.each(details, function( detail, callback ) {
beforeModifyProductStock = {
storeInvoiceDetail: storeInvoiceDetail(detail),
getPreviousDetail: getPreviousDetail,
createPreviousDetail: createPreviousDetail,
getStockDifference: getStockDifference,
updateProductStock: updateProductStock
};
async.auto(beforeModifyProductStock, function( err, results ) {
console.log('now latest stock is ' + results.updateProductStock);
callback();
});
}, function (err) {
// no action
});
}
.save() is an asynchronous method. Rewrite your updateProductStock function as:
var updateProductStock = ['getPreviousDetail', 'getStockDifference', function( cb, results ) {
Product
.findOne(results.getPreviousDetail.product)
.then(function(product) {
product.stock += results.getStockDifference;
// Note the callback argument to .save()
product.save(function(err, product) {
console.log(product.stock);
cb(err, product.stock);
});
});
}];
and you should be okay.
I have 2 tables in parse
Memories and Locations with a relation One-To-One, but the pointer is in Location table ( Pointer )
What i need is to read all memories ten by ten with skip and limit and for each memory to atach a property with location object
By now i have this:
var _ = require('underscore.js');
Parse.Cloud.define("feed", function(request, response) {
var memories = Parse.Object.extend("Memories");
var memoriesQuery = new Parse.Query(memories);
memoriesQuery.skip(0);//request.params.skip);
memoriesQuery.limit(10);//request.params.limit);
memoriesQuery.descending("createdAt");
memoriesQuery.include("group");
var parsedResults = [];
memoriesQuery.find().then(function(memories) {
var promise = Parse.Promise.as();
_.each(memories, function(memory) {
promise = promise.then(function() {
var locations = Parse.Object.extend("Locations");
var locationsQuery = new Parse.Query(locations);
locationsQuery.equalTo("memory", memory);
var subPromise = Parse.Promise();
locationsQuery.first().then(function(location) {
memory["location"] = location;
console.log(JSON.stringify(memory) + " ........ " + memory["location"]);
console.log("=============");
parsedResults.push(memory);
subPromise.resolve(memory);
});
return subPromise ;
});
console.log("-----------");
console.log("Promise:" +promise.toString());
});
return promise;
}).then(function(){
response.success(parsedResults);
});
});
I have no clue what to do.. More than 10 hours of tries.
I appreciate any help!
Finally solved!
Maybe it will help somebody.
Solution:
var _ = require('underscore.js');
var memoriesResult = [];
Parse.Cloud.define("feed", function(request, response) {
var promises = [];
var promise = findMemories();
promise.then(function(memories){
console.log("success promise!!");
_.each(memories, function (memory) {
console.log("each");
promises.push(findLocation(memory));
});
return Parse.Promise.when(promises);
}).then(function(){
console.log("Finish");
response.success(memoriesResult);
}, function(error){
console.error("Promise Error: " + error.message);
response.error(error);
});
});
function findMemories(){
console.log("Enter findMemories");
var memories = Parse.Object.extend("Memories");
var memoriesQuery = new Parse.Query(memories);
memoriesQuery.skip(0);//request.params.skip);
memoriesQuery.limit(10);//request.params.limit);
memoriesQuery.descending("createdAt");
memoriesQuery.include("group");
var promise = new Parse.Promise();
memoriesQuery.find().then(function(memories) {
console.log("Memories found!");
promise.resolve(memories);
}, function(error) {
promise.reject(error);
});
return promise;
}
function findLocation(memory) {
console.log("Enter findLocation");
var locations = Parse.Object.extend("Locations");
var locationsQuery = new Parse.Query(locations);
locationsQuery.equalTo("memory", memory);
var promise = new Parse.Promise();
locationsQuery.first().then(function(location) {
console.log("Location found");
memoriesResult.push({"memory": memory, "location" : location});
promise.resolve(memory);
}, function(error) {
promise.reject(error);
});
return promise;
}
After doing some experiments, I've come up with the following requirements and solution:
You want to page through Memories items a page at a time, sorted by their createdAt
You want the Locations related to each memory
You are limited by the fact that the relationship is Locations->Memories
Your first step is to define the query for memories:
var memoryQuery = new Parse.Query('Memories');
memoryQuery.skip(request.params.skip);
memoryQuery.skip(request.params.limit);
memoryQuery.descending('createdAt');
You can now use this query to limit the Locations objects returned. If your links are all setup correctly you will get back 10 records:
var locationQuery = new Parse.Query('Locations');
// limit to only the page of Memory items requested
locationQuery.matchesQuery('memory', memoryQuery);
// include the Memory pointer's data
locationQuery.include('memory');
var memoriesResult = [];
locationQuery.find().then(function(locations) {
var result = _.map(locations, function(location) {
memory: location.get('memory'),
location: location
});
response.success(result);
}, function(error) {
response.error(error);
});
The only issue with the above is that I'm not sure on the order of the returned records, so you might want to re-sort them before returning them. That is extremely simple though with the underscore library.
This will result in 2 queries no matter the page size.
My problem is when I check one of the checkboxs and then I search it, the checkbox will change to uncheck. and I don`t know what's wrong with my livesearch, it is not working.
please check this link to test.
http://jsfiddle.net/v921/KmVHf/4/
is is my javascript
var tr = $(".AvailableGroupLab").clone().html();
function filter(element) {
$('.AvailableGroupLab').html(tr);
var value = $(element).val().toLowerCase();
$(".AvailableGroupLab tr").each(function () {
if ($(this).text().toLowerCase().search(value) == -1){
$(this).remove();
}
});
}
Try
function filter(element) {
var $trs = $('.AvailableGroupLab tr').hide();
var regexp = new RegExp($(element).val(), 'i');
var $valid = $trs.filter(function () {
return regexp.test($(this).children(':nth-child(2)').text())
}).show();
$trs.not($valid).hide()
}
$('input:text').on('keyup change', function () {
filter(this);
})
Demo: Fiddle