optimize a SQL query for a couchdb view - sql

How to optimize this SQL query for a couchdb view ?
SELECT * FROM db WHERE user = '$userid' OR userFollowed = '$userid'
The couchdb database contains this structure of documents:
_id
user
userFollowed
This because a user can follows another and viceversa and my scope is to get all followers of user A that this user which follows it turn, for example:
A follows B
B follows A
In this example I need to get B, enstabilishing that both users are followers... I know it's complex to explain and understand but I'll try with the things I'm doing with node.js and cradle.
The view map:
function (doc) {
emit(doc.user, doc.userFollowed)
}
The node.js code:
db.view("followers/getFollowers", function(err, resp) {
if (!err) {
var followers = [];
resp.forEach(function(key, value, id) {
var bothFollow = false;
if (key == userID) {
if (followers.indexOf(value) == -1) {
resp.forEach(function(key, value, id) {
if (value == userID)
bothFollow = true;
});
if (bothFollow)
followers.push(value);
}
} else if (value == userID) {
if (followers.indexOf(key) == -1) {
resp.forEach(function(key, value, id) {
if (key == userID)
bothFollow = true;
});
if (bothFollow)
followers.push(key);
}
}
});
console.log(followers);
}
});
So in the code first I check if the A or B values corrispondes to the other user, then check with another loop if there is a relationship putting the follower in the list
All this code works but I don't think that's the correct procedure and maybe I'm wrong anything :( can you help me please ?

It is easier to emit both users in the view function:
function (doc) {
emit(doc.user, null);
emit(doc.userFollowed, null);
}
Than you can just call the view and will get a plain list:
http://localhost:5984/db/_design/app/_view/followers?include_docs=true

Related

MVC Entity Framework, Query returns null

Hi guys can you help me understand why i keep getting a null instead of get the value.
Need to receive the saidaservicoid to be able to update. I receive the value from the view but can't update elemento. Stays null.
Thanks in advance for the help.
[Database]
[elementoRepository]
public async Task UpdateElementoSaidaServicosAsync(AddSaidasServicoViewModel model)
{
var saidaServico = await _context.SaidaServicos.FindAsync(model.SaidaServicoId);
var elemento = await _context.Elementos.FindAsync(model.ElementoId);
if (elemento == null)
{
return;
}
var updateElementoSaida = _context.Elementos.Where(e => e.Id == model.ElementoId).FirstOrDefault();
if (updateElementoSaida == null)
{
updateElementoSaida = new Elemento
{
saidaServico = saidaServico,
};
_context.Elementos.Update(updateElementoSaida);
}
else
{
int SaidaServicos = model.SaidaServicoId;
updateElementoSaida.saidaServico = saidaServico;
}
await _context.SaveChangesAsync();
return;
}
Ok. the best way that i found to solve this issue was to get the last ID.
int SaidaServicos = _context.SaidaServicos.Max(item => item.Id);

Easiest way to check record is exist or not in Linq to Entity Query

in store procedure we can check record is exist or not using following query for fast performance
if EXISTS ( Select 1 from Table_Name where id=#id )
But what about Linq query.
right now i have to store whole data in object like this
UserDetail _U=db.UserDetails.where(x=>x.id==1).FirstOrDefault();
Any Solution?
Use Linq's Any ie bool exist = db.UserDetails.Any(x => x.id == 1);
if(db.UserDetails.Any(x => x.id == 1)) {
var userDetail = db.UserDetails.FirstOrDefault(x => x.id == 1);
}
bool exist = db.UserDetails.Where(x=>x.id==1).Any();
if(exist){
//your-code
}else{
//your-code
}
Just check
if(_U == null)
This way you will get what you want in single query and you not need to execute addition query like
db.UserDetails.Any(x => x.id == 1)
I think, it does not require to fire two query. It can be accomplish by single query.
UserDetails objUserDetails =db.UserDetails.FirstOrDefault(x => x.id == 1);
if(objUserDetails==null)
{
// Do something
}
else
{
// do something with objUserDetails
}
var qry = db.User_Detail.Where(x => x.User_Id == 1).FirstOrDefault();
if(qry !=null)
{
// Do something
}
else
{
return false;
}
Try This...

Yii check scenario in beforeSave()

For one action I need transform $album_id before save it to DB
in model function beforeSave() i do:
// преобразовать album -> album_id
$album_id=array();
foreach($this->string2array($this->album, '\|') as $one)
$album_id[]=Album::model()->findByAttributes(array('album' => $one))->id;
$this->album_id = $this->array2string($album_id);
but for another action I don't need this transform, because $album_id is already in proper state. So I set scenario 'batchcreate' in that action:
public function actionCreate()
{
Yii::import('ext.multimodelform.MultiModelForm');
$model = new Album('create');
$song = new Song();
$song->setScenario('batchcreate');
...
}
and try to check this scenario in model:
if(!($this->scenario === 'batchcreate')) {
// преобразовать album -> album_id
$album_id=array();
foreach($this->string2array($this->album, '\|') as $one)
$album_id[]=Album::model()->findByAttributes(array('album' => $one))->id;
$this->album_id = $this->array2string($album_id);
}
but the condition is always true. Why my scenario doesn't set or doesn't check in if statement?
Or maybe it's better to check not scenario, but make another variable, so how to set its value for 2 different cases?
my whole beforeSave():
protected function beforeSave()
{
if(parent::beforeSave())
{
// преобразовать whoes -> who
$who=array();
foreach($this->string2array($this->whoes) as $one) {
$userrow = User::model()->findByAttributes(array('username' => $one));
if($userrow) $who[]=CHtml::encode($userrow->id);
else $who[]=$one;
}
$this->who = $this->array2string($who);
//var_dump( $this->scenario );
if(!($this->scenario == 'batchcreate')) {
//if($this->notbatchcreate == 'yes') {
// преобразовать album -> album_id
$album_id=array();
foreach($this->string2array($this->album, '\|') as $one)
$album_id[]=Album::model()->findByAttributes(array('album' => $one))->id;
$this->album_id = $this->array2string($album_id);
}
return true;
}
else
return false;
}
Instead of
$song = new Song();
$song->setScenario('batchcreate');
you can simply do
$song = new Song('batchcreate');
In beforeSave()
if ( $this->scenario != 'batchcreate' ) {
echo "good - scenario is not batchcreate";
die();
}
echo 'nope...';
var_dump($this->scenario);
die();
Switch the order: call parent::beforeSave() after your code for checking the scenario. The inherited method beforeSave() may be altering your scenario.

How to compare QML string from a SQLight DataBase

I've being trying to create a match string function which will read a SQLLite (javascript created) Database from qml and match the string (web address given to it in my case), this is my Database file code:
.pragma library
var db;
// opens database at launch
function openDB()
{
db = openDatabaseSync("BookmarksDB","1.0","Bookmarks Database",1000000);
createTable();
}
// creates table if it doesn't exist, otherwise ignores
function createTable()
{
db.transaction(
function(tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS bookmarks (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, url TEXT, creationdate TEXT, modified DATETIME)");
}
)
}
// deletes table
function dropTable()
{
db.transaction(
function(tx) {
tx.executeSql("DROP TABLE IF EXISTS bookmarks");
}
)
}
// creates a single bookmark record
function createBookmark(bookmarkItem)
{
db.transaction(
function(tx) {
tx.executeSql("INSERT INTO bookmarks (title, url, creationdate, modified) VALUES(?,?,?,?)",[bookmarkItem.title, bookmarkItem.url, bookmarkItem.creationdate, bookmarkItem.modified]);
}
)
}
// updates a single bookmark record
function updateBookmark(bookmarkItem)
{
db.transaction(
function(tx) {
tx.executeSql("UPDATE bookmarks SET title = ?, url = ?, creationdate = ?, modified = ? WHERE id = ?",
[bookmarkItem.title, bookmarkItem.url, bookmarkItem.creationdate, bookmarkItem.modified, bookmarkItem.id]);
}
)
}
// deletes a single bookmark record
function deleteBookmark(id)
{
db.transaction(
function(tx) {
tx.executeSql("DELETE FROM bookmarks WHERE id = ?", [id]);
}
)
}
// read list of bookmarks
function readBookmarkList(model)
{
model.clear();
var sqlstring = "SELECT id, title, url, creationdate FROM bookmarks";
db.readTransaction(
function(tx) {
var rs;
rs = tx.executeSql(sqlstring);
for (var i = 0; i < rs.rows.length; i++) {
model.append(rs.rows.item(i))
}
}
)
}
// read a single bookmark item
function readBookmarkItem(id) {
var data = {}
db.readTransaction(
function(tx) {
var rs = tx.executeSql("SELECT * FROM bookmarks WHERE id=?", [id])
if(rs.rows.length === 1) {
data = rs.rows.item(0)
}
}
)
return data;
}
// create a default bookmark item
function defaultItem()
{
return {title: "", url: "", creationdate: new Date(), modified: new Date()}
}
I was wanting to create something like,
function checkUrl(url){
if(dbvalues == url) {
return true
}
else{return false}
}
}
But I haven't a clue how to read all the data from the tables and get it to compare with the url given in the function.
Can somebody please help me out?
I'm a complete noob with SQL stuff
Using Qt Quick 1.1 on Symbian
Why don't you try something like
function checkURL(url) {
var exists
db.readTransaction(function(tx) {
var sql = "SELECT url FROM bookmarks WHERE url=? LIMIT 1";
var rs = tx.executeSql(sql, [url])
exists = rs.rows.length > 0
})
return exists
}
LIMIT 1 clause will tell DB engine to stop searching when it finds the first row matching your criteria.
Haven't tried this myself, but it should work.

WPF application Linq to sql getting data

I'm making a WPF application with a datagrid that displays some sql data.
Now i'm making a search field but that doesn't seem to work:
Contactpersoon is an nvarchar
bedrijf is an nvarchar
but
LeverancierPK is an INT
How can I combinate that in my search?
If i convert LeverancierPK to string, then I can use Contains but that gives me an error
//Inisiatie
PRCEntities vPRCEntities = new PRCEntities();
var vFound = from a in vPRCEntities.tblLeveranciers
where ((((a.LeverancierPK).ToString()).Contains(vWoord)) ||
(a.Contactpersoon.Contains(vWoord)) ||
(a.Bedrijf.Contains(vWoord)))
orderby a.LeverancierPK
select a;
myDataGrid_Leveranciers.ItemsSource = vFound;
Thanks
If you don't care about pulling all records back from the DB (which in your answer you pulled everything back), then you can just do a .ToList() before the where clause.
var vFound = vPRCEntities.tblLeveranciers.ToList()
.Where(a => a.LeverancierPK.ToString().Contains(vWoord)) ||
a.Contactpersoon.Contains(vWoord) ||
a.Bedrijf.Contains(vWoord))
.OrderBy(a.LeverancierPK);
This code can do what I was looking for but I think it could be alot shorter.
PRCEntities vPRCEntities = new PRCEntities();
var vFound = from a in vPRCEntities.tblLeveranciers
orderby a.LeverancierPK
select a;
myDataGrid_Leveranciers.ItemsSource = null;
myDataGrid_Leveranciers.Items.Clear();
foreach (var item in vFound)
{
if (item.Bedrijf.Contains(vWoord))
{
myDataGrid_Leveranciers.Items.Add(item);
}
else
{
if (item.LeverancierPK.ToString().Contains(vWoord))
{
myDataGrid_Leveranciers.Items.Add(item);
}
else
{
if (item.Contactpersoon != null)
{
if (item.Contactpersoon.Contains(vWoord))
{
myDataGrid_Leveranciers.Items.Add(item);
}
}
}
}
}