How can i perform not contains query in sequelize - postgresql

I'm using sequelize with postgres,
Is there a way to perform a "not contains" statement with sequelize?
something like:
[Op.not]: {
[Op.contains]: ['value1','value2']
}
which produces:
SELECT * FROM Table WHERE NOT ArrayColumn #>ARRAY['value1','value2']::VARCHAR(255)[]

had the same issue had to go to rawish SQL
where['<COL_NAME>'][Op.and] = [Sequelize.literal(`'${JS_VARIABLE_ARRAY}' != all (<COL_NAME>)`)];
I've built this helper function to construct the my where query
const buildWhereQuery = (query, columns) => {
const parsedObject = {};
Object.keys(query).forEach((attr) => {
if (columns.indexOf(attr) !== -1 && (query[attr] !== null || query[attr] !== undefined)) {
parsedObject[attr] = query[attr];
}
});
return parsedObject;
};
const where = buildWhereQuery(query, columnsToQueryAgainst)
hope that's help.
using:
node: v10.14.2
sequelize#4.38.0
sequelize-cli#4.0.0

You can use as
where: {
$not: { $contains: ['value1','value2'] },
}

Related

Getting issue while fetching prev/next post from Sanity CMS ( Next js +Sanity static blog)

I'm using Sanity CMS, and trying to fetch previous and next post using this query below.
const query = `*[_type=='post' && slug.current == $slug][0]{
_id,title,_updatedAt,
"newPost" : *[_type == 'post' && ^._updatedAt > _updatedAt][0] {
title,"slug" : slug.current
}
}`;
const param = {
slug: "some-random-slug",
};
const nextPrev = await client.fetch(query, param);
My problem is that when I tried this above query at Sanity Vision, it works perfectly. But while trying this with sanity client, it doesn't return the newPost object. What's wrong with me?
Try this:
const query = `*[_type == "post" && slug.current == $slug][0] {
"nextPost": *[_type == "post" && ^._createdAt < _createdAt] | order(_createdAt asc)[0] {
// Fields
}
}`
const { nextPost } = await client.fetch(query, { slug })

w2ui filter option "contains not" possible?

I am using w2ui (1.5) and I would be interested in whether it is possible to use a filter that only delivers negative results
That means only records/keys which not fullfilling a certain criteria.
Like a condition "contains not" or "is not" in addition to
http://w2ui.com/web/docs/1.5/w2grid.textSearch.
Thanks!
Gordon
okay, a possible solution is
w2ui['grid'].search([{ field: var1, value: var2, operator: 'not in'}], 'OR');
I coded my own solution to this problem. This adds a way to use "not" for string and "!=" for number searches.
This function does the search and it is also used to store the grid advanced search popup in history state.
I'm sure this can be even more optimized, so please use this more like a guideline. Hope this helps somebody.
function searchExtend(event, grid) {
// if event is null, we do just the local search
var searchObj;
if (event == null) {
searchObj = grid;
} else {
searchObj = event;
}
// make a copy of old data
const oldSearchData = structuredClone(searchObj.searchData);
const oldSearchLogic = structuredClone(searchObj.searchLogic);
var searchData = searchObj.searchData;
var invertedSdata = [];
var toSplice = [];
// check operator if it's "not" or "!="
for (var i = 0; i < searchData.length; i++) {
var sdata = searchData[i];
// invert the condition
if (sdata.operator == "not") {
toSplice.push(i);
invertedSdata.push({
field: sdata.field,
type: sdata.type,
operator: "contains",
value: sdata.value
});
}
if (sdata.operator == "!=") {
toSplice.push(i);
invertedSdata.push({
field: sdata.field,
type: sdata.type,
operator: "=",
value: sdata.value
});
}
}
// remove all "not" and "!=" from searchData
for (var i in toSplice) {
searchData.splice(i, 1);
}
var foundIds = [];
// use inverted criteria to search
if (invertedSdata.length > 0) {
grid.searchData = invertedSdata;
grid.searchLogic = "OR";
grid.localSearch();
grid.searchLogic = oldSearchLogic;
// store found ids
foundIds = structuredClone(grid.last.searchIds);
}
if (foundIds.length > 0) {
// perform a search with original criteria - spliced "not" and "!="
grid.searchData = searchData;
grid.localSearch();
var allRecIds = structuredClone(grid.last.searchIds);
// if there's not any results, push push all recIds
if (grid.last.searchIds.length == 0) {
for (let i = 0; i < grid.records.length; i++) {
allRecIds.push(i);
}
}
// remove all ids found with inverted criteria from results. This way we do the "not" search
for (const id of foundIds) {
allRecIds.splice(allRecIds.indexOf(id), 1);
}
if (event != null) {
// let the search finish, then refresh grid
event.onComplete = function() {
refreshGrid(grid, allRecIds, oldSearchData);
setSearchState(grid);
}
} else {
// refresh the grid
refreshGrid(grid, allRecIds, oldSearchData);
setSearchState(grid);
}
return;
}
if (event != null) {
event.onComplete = function() {
setSearchState(grid); // store state
}
} else {
// refresh whole grid
refreshGrid(grid, allRecIds, oldSearchData);
setSearchState(grid);
}
}
function refreshGrid(grid, allRecIds, oldSearchData) {
grid.last.searchIds = allRecIds;
grid.total = grid.last.searchIds.length;
grid.searchData = oldSearchData;
grid.refresh();
}
function setSearchState(grid) {
history.replaceState(JSON.stringify(grid.searchData), "Search");
}
To use this, you have to call it from the grid's onSearch:
onSearch: function(event) {
searchExtend(event, w2ui["grid"]);
}
Also, if you want to use the history.state feature, it needs to be called from onLoad function:
onLoad: function(event) {
event.onComplete = function() {
console.log("History state: " + history.state);
if (history.state != null) {
w2ui["grid"].searchData = JSON.parse(history.state);
searchExtend(null, w2ui["grid"]);
}
}
To add operators, please use this reference.
This is my solution to the problem:
operators: {
'text': ['is', 'begins', 'contains', 'ends', 'not'], // could have "in" and "not in"
'number': ['=', 'between', '>', '<', '>=', '<=', '!='],
'date': ['is', 'between', {
oper: 'less',
text: 'before'
}, {
oper: 'more',
text: 'after'
}],
'list': ['is'],
'hex': ['is', 'between'],
'color': ['is', 'begins', 'contains', 'ends'],
'enum': ['in', 'not in']
}

MongoDB function and how to call it?

I'm new to MongoDB and I found this function on the web. it's going to work for my all queries.
For settings.amount, settings.balance etc..
exports.updateUsers = function ( user_id, where, what, pass ) {
var _where = 'settings.'+where; //when I use it doesn't update
var update = {};
update[_where] = what;
user.findOneAndUpdate(
{'user_id' : user_id},
update).exec(function(e,d){
pass("ok")
})
};
Could anyone explain to me how can I call this query to update balance or amount?
Could anyone give me an example of updating something?
You can use it like this:
const { updateUsers } = require('./pathToFile.js'); // add the correct path;
// assuming you want to update the balance of a user to 69
updateUsers('some id', 'balance', 69, (result) => {
if(result === 'ok') {
// do something
} else if(result === 'bad') {
// you have an error
}
})
I would also change updateUsers to handle errors:
exports.updateUsers = function (user_id, where, what, pass) {
var _where = 'settings.' + where; //when I use it doesn't update
var update = {};
update[_where] = what;
user.findOneAndUpdate(
{ 'user_id': user_id },
update).exec(function (error, d) {
if (!error) {
pass('ok');
} else {
pass('bad')
}
})
};

Find unused indexes in MongoDB [duplicate]

I have a mongodb replica set with a lot of databases, collections & indexes.
We did a lot of refactor and optimization and, of course, I have a lot of "creative queries" from the consumers.
I would like to clean up the unused indexes. just wanna save some space.
How can I check if an index is being used? I can afford to check index by index and drop the unused ones.
Running an "explain" in all the possible queries is not an option :)
EDIT: SOLUTION BASED ON THE ACCEPTED ANSWER
The script was bugged. I am not a javascript expert, but I put the corrected script. I hope will be useful for someone:
DB.prototype.indexStats = function() {
var queries = [];
var collections = db.getCollectionNames();
var findQuery = function(q) {
for(entryIdx in queries) {
if(q == queries[entryIdx].query) {
return entryIdx;
}
}
return -1;
}
for(cIdx in collections) {
var cName = collections[cIdx];
var nsName = db.getName()+"."+cName;
if(cName.indexOf("system") == -1) {
var i = 1;
var count = db.system.profile.count({ns:nsName});
print('scanning profile {ns:"'+nsName+'"} with '+count+' records... this could take a while...');
db.system.profile.find({ns:nsName}).addOption(16).batchSize(10000).forEach(function(profileDoc) {
if(profileDoc.query && !profileDoc.query["$explain"]) {
var qIdx = findQuery(profileDoc.query);
if(qIdx == -1 && profileDoc.query["query"] ) {
var size = queries.push({query:profileDoc.query, count:1, index:""});
var explain = db[cName].find(queries[size-1].query).explain();
if(profileDoc.query && profileDoc.query["query"]) {
queries[size-1].sort = profileDoc.query["orderby"];
if(queries[size-1].sort) {
explain = db[cName].find(queries[size-1].query.query).sort(queries[size-1].sort).explain();
}
}
queries[size-1].cursor = explain.cursor;
queries[size-1].millis = explain.millis;
queries[size-1].nscanned = explain.nscanned;
queries[size-1].n = explain.n;
queries[size-1].scanAndOrder = explain.scanAndOrder ? true : false;
if(explain.cursor && explain.cursor != "BasicCursor") {
queries[size-1].index = explain.cursor.split(" ")[1];
} else {
print('warning, no index for query {ns:"'+nsName+'"}: ');
printjson(profileDoc.query);
print('... millis: ' + queries[size-1].millis);
print('... nscanned/n: ' + queries[size-1].nscanned + '/' + queries[size-1].n);
print('... scanAndOrder: ' + queries[size-1].scanAndOrder);
}
} else if ( qIdx != -1 ) {
queries[qIdx].count++;
}
}
});
}
}
for(cIdx in collections) {
var cName = collections[cIdx];
if(cName.indexOf("system") == -1) {
print('checking for unused indexes in: ' + cName);
for(iIdx in db[cName].getIndexes()) {
var iName = db[cName].getIndexes()[iIdx].name;
if(iName.indexOf("system") == -1) {
var stats = db[cName].stats();
var found = false;
for(qIdx in queries) {
if(queries[qIdx].index == iName) {
found = true;
break;
}
}
if(!found) {
print('this index is not being used: ');
printjson(iName);
}
}
}
}
}
}
The simplest solution to this is to use the mongodb inbuilt $indexStats aggregation stage, added in MongoDB 3.2.
Using the Mongo console:
db.collection.aggregate([ { $indexStats: { } } ])
Using PyMongo:
from pymongo import MongoClient
collection = MongoClient()[db_name][collection_name]
index_stats = collection.aggregate([{'$indexStats':{}}])
for index_info in index_stats:
print index_info
There is a pretty cool script out on Github that you should look at:
https://github.com/wfreeman/indexalizer
Basically it involves turning on profiling for your database and then it will use the data collected by the profiler to drive explain() calls. It then tells you both which indexes are not being used and which queries are not using indexes. Pretty slick.
More about mongoDB database profiling:
http://docs.mongodb.org/manual/reference/database-profiler/

How do I check if an index is being used

I have a mongodb replica set with a lot of databases, collections & indexes.
We did a lot of refactor and optimization and, of course, I have a lot of "creative queries" from the consumers.
I would like to clean up the unused indexes. just wanna save some space.
How can I check if an index is being used? I can afford to check index by index and drop the unused ones.
Running an "explain" in all the possible queries is not an option :)
EDIT: SOLUTION BASED ON THE ACCEPTED ANSWER
The script was bugged. I am not a javascript expert, but I put the corrected script. I hope will be useful for someone:
DB.prototype.indexStats = function() {
var queries = [];
var collections = db.getCollectionNames();
var findQuery = function(q) {
for(entryIdx in queries) {
if(q == queries[entryIdx].query) {
return entryIdx;
}
}
return -1;
}
for(cIdx in collections) {
var cName = collections[cIdx];
var nsName = db.getName()+"."+cName;
if(cName.indexOf("system") == -1) {
var i = 1;
var count = db.system.profile.count({ns:nsName});
print('scanning profile {ns:"'+nsName+'"} with '+count+' records... this could take a while...');
db.system.profile.find({ns:nsName}).addOption(16).batchSize(10000).forEach(function(profileDoc) {
if(profileDoc.query && !profileDoc.query["$explain"]) {
var qIdx = findQuery(profileDoc.query);
if(qIdx == -1 && profileDoc.query["query"] ) {
var size = queries.push({query:profileDoc.query, count:1, index:""});
var explain = db[cName].find(queries[size-1].query).explain();
if(profileDoc.query && profileDoc.query["query"]) {
queries[size-1].sort = profileDoc.query["orderby"];
if(queries[size-1].sort) {
explain = db[cName].find(queries[size-1].query.query).sort(queries[size-1].sort).explain();
}
}
queries[size-1].cursor = explain.cursor;
queries[size-1].millis = explain.millis;
queries[size-1].nscanned = explain.nscanned;
queries[size-1].n = explain.n;
queries[size-1].scanAndOrder = explain.scanAndOrder ? true : false;
if(explain.cursor && explain.cursor != "BasicCursor") {
queries[size-1].index = explain.cursor.split(" ")[1];
} else {
print('warning, no index for query {ns:"'+nsName+'"}: ');
printjson(profileDoc.query);
print('... millis: ' + queries[size-1].millis);
print('... nscanned/n: ' + queries[size-1].nscanned + '/' + queries[size-1].n);
print('... scanAndOrder: ' + queries[size-1].scanAndOrder);
}
} else if ( qIdx != -1 ) {
queries[qIdx].count++;
}
}
});
}
}
for(cIdx in collections) {
var cName = collections[cIdx];
if(cName.indexOf("system") == -1) {
print('checking for unused indexes in: ' + cName);
for(iIdx in db[cName].getIndexes()) {
var iName = db[cName].getIndexes()[iIdx].name;
if(iName.indexOf("system") == -1) {
var stats = db[cName].stats();
var found = false;
for(qIdx in queries) {
if(queries[qIdx].index == iName) {
found = true;
break;
}
}
if(!found) {
print('this index is not being used: ');
printjson(iName);
}
}
}
}
}
}
The simplest solution to this is to use the mongodb inbuilt $indexStats aggregation stage, added in MongoDB 3.2.
Using the Mongo console:
db.collection.aggregate([ { $indexStats: { } } ])
Using PyMongo:
from pymongo import MongoClient
collection = MongoClient()[db_name][collection_name]
index_stats = collection.aggregate([{'$indexStats':{}}])
for index_info in index_stats:
print index_info
There is a pretty cool script out on Github that you should look at:
https://github.com/wfreeman/indexalizer
Basically it involves turning on profiling for your database and then it will use the data collected by the profiler to drive explain() calls. It then tells you both which indexes are not being used and which queries are not using indexes. Pretty slick.
More about mongoDB database profiling:
http://docs.mongodb.org/manual/reference/database-profiler/