how to find specific string in key value pair in mongodb - node.js

i am having data in mongodb like that
[
{
"name":"silvester",
"product":"laptop,iphone,mobile,phone"
},
{
"name":"john",
"product":"cycle,bus,phone,laptop"
},
{
"name":"franklin",
"product":"cycle,phone"
}
]
How to find that laptop is in product key.
if product key look like this
{
"name":"XXX",
"product":"laptop"
}
I can easily find that name by using this db.collection.find("product":"laptop");
So how to find this?
Also let me know this three website name running under using backbone.js and node.js and mongodb technology such as www.trello.com .
sorry for my worst english..

Using regex with mongodb
This worked for me
db.collection.find({"product": /laptop/})
Updated Answer
If you wish to use variables, try something like this:
var abc = "laptop";
// other stuff
userdetails.find({"product":new RegExp(abc)}).toArray(function(err,result){
if (err) console.log ("error: "+err);
else
{
// if you want the length
console.log(result.length);
// if you actually want to see the results
for (var i = 0; i < result.length; i++)
{
console.log(result[i]);
}
}
});
Updated One More Time
var abc = "laptop";
// other stuff
// note this is case sensitive. if abc = "Laptop", it will not find it
// to make it case insensitive, you'll need to edit the RegExp constructor
// to this: new RegExp("^"+abc+",|, "+abc+"(?!\w)", "i")
userdetails.find({"product":new RegExp("^"+abc+",|, "+abc+"(?!\w)")}).toArray(function(err,result){
if (err) console.log ("error: "+err);
else
{
// if you want the length
console.log(result.length);
// if you actually want to see the results
for (var i = 0; i < result.length; i++)
{
console.log(result[i]);
}
}
});

regex will work perfectly fine. there is also good news for you as monogdb will be releasing full text search index in the upcoming version
http://docs.mongodb.org/manual/release-notes/2.4/#text-indexes

Related

How to remove specific object from object array in localStorage

Can anybody advise me how I should go about adapting this code to remove the found object within an array of objects in localStorage.
So far everything I have tried results in either only the 1st object being removed or none at all.
I have tried using the following adaptations to the splice request, but it has not removed the selected object.
favorites.splice(favorites, [i]);
favorites.splice(favorites, 1);
favorites.splice(favorites, favorites[i]);
ect ect
I have also tried using the ifIncludes request but then again removing the individual object has been troublesome.
function checkfave (theid) {
// get favorites from local storage or empty array
var favorites = JSON.parse(localStorage.getItem('favorites')) || [];
var theimage = $('#theimage'+theid).attr('src');
var thetitle = $('#thetitle'+theid).text();
var theprice = $('#theprice'+theid).text();
var added=true;
//Loop through the Favorites List and display in console (HIDDEN)
console.clear();
for (let i = 0; i < favorites.length; i++) {
console.log(i)+'items added';
if ( favorites[i].ID == theid ) {
var answer = window.confirm('You already Added To Your Favorites \r\r '+thetitle+' \r\r Do You Want To Remove It? ');
if (answer) { // choose to remove
favorites.splice(favorites[i], [i]);
alert(thetitle+' \r\r Has Been Removed From Your Favorites \r\r At Position'+[i]);
var added=false; break; //IMPORTANT KILLS THE LOOP ONLY IF favorites[i].ID == theid
}else {
var added=false; break;
}
}
}//for loop
if (added===true) {
favorites.push({ID:theid,IMAGE:theimage,TITLE:thetitle,PRICE:theprice});
localStorage.setItem('favorites', JSON.stringify(favorites));
alert('You Just Added To Your Favorites \r\r '+thetitle);
}
console.log(localStorage.favorites);
}//function
console log is returning in this format
favorites
(2) [{…}, {…}]
0
:
{ID: 32921, IMAGE: 'uploads/posts/2017-07/1500056645_apulsoft-apqualizr-2.png', TITLE: 'ApulSoft apQualizr 2 v2.5.2 ', PRICE: '19.99'}
1
:
{ID: 32920, IMAGE: 'uploads/posts/2022-03/1003229…cdj-lyrx-karaoke-player-software-for-mac-pc-1.png', TITLE: 'PCDJ LYRX v1.8.0.2 / v1.9.0.0 U2B ', PRICE: '19.99'}
length
:
2
[[Prototype]]
:
Array(0)
`
Finally figured it out on my own. Thanks
for (let i = 0; i < favorites.length; i++) {
console.log(i)+'items added';
if ( favorites[i].ID == theid ) {
var answer = window.confirm('You already Added To Your Favorites \r\r '+thetitle+' \r\r Do You Want To Remove It? ');
if (answer) { // choose to remove
favorites.splice(i, 1);
localStorage.setItem('favorites', JSON.stringify(favorites));
alert(thetitle+' \r\r Has Been Removed From Your Favorites \r\r At Position'+[i]);
var added=false; break; //IMPORTANT KILLS THE LOOP ONLY IF favorites[i].ID == theid
}else {
var added=false; break;
}
}
}//for loop
I was misunderstanding the nature of the splice function. i was trying to use favourites[i] = when favorites was already assumed in the 1st instance of the splice call.
I eventually came across the answer online in a similar situation.
the answer was to splice this way to remove at position i and remove 1 item
favorites.splice(i, 1);
Thanks anyway guys.

project oxford text not printing correctly

I'm using project oxfords modules and I trying to print out the text in the image
when i print response it looks like this. My guess is the text is in the 'lines'. How do i print that?
client3 = new oxford.Client('api key')
client3.vision.ocr({
path: './words.jpg',
language: 'en',
}).then(function (response) {
console.log(response);
}).catch(function (err) {
console.log(err);
});
probably a simple fix I just cant figure it out
There's a sample JSON here.
Basically, lines is an array of an object consisting of a boundingBox and words. words, in turn, is an array of object consisting of a boundingBox and text.
So for example, you could do something like this:
for (i=0; i<response.regions.length; i++) {
region = response.regions[i];
for (j=0; j<region.lines.length; j++) {
line = region.lines[j];
words = [];
for (k=0; k<line.words.length; k++) {
words.push(line.words[k].text);
}
console.log(words.join(' '));
}
}

Adding functions in search index of loudant

I have a Json document in cloudant as:
{
"_id": "3-f812228f45b5f4e4962505561953ew245",
"_rev": "3-f812228f45b5f4e496250556195372b2",
"wiki_page": "http://en.wikipedia.org/wiki/African_lion",
"name": "african lion",
"class": "mammal",
"diet": "herbivore"
}
I want to make a search index that can search this document when I input queries as "afrian lion" or "lion african",...
I make a function that can return all cases of permutation in "doc.name" for indexing (This function works well and it also had been checked in pure JS environment). However, it does't work in cloudant, the output return null when i input a query.
This is a code that I made in search index:
function(doc){
var list = [];
function permute(ss, used, res, level, list){
if(level==ss.length&&res!==""){
list.push(res);
return;
}
for(var i=0; i<ss.length; i++){
console.log("loops");
if (used[i]===true){
continue;
}
if(level>=0){
if (res!="" && list.indexOf(res)<0){
list.push(res.trim());
}
used[i]=true;
permute(ss, used, res+" "+ss[i], level+1, list)
used[i]=false;
}
}
}
function permuteword(s){
var ss=s.split(" ");
var used = [];
var res = "";
list = [];
permute(ss, used, res, 0, list);
console.log(list);
}
var contentIndex=[];
contentIndex=permuteword("african lion");
for(var i=0; i<contentIndex.length; i++){
index("default", contentIndex[i]);
}
}
How can i solve the problem?
Update
Your update looks good, but there is still one issue: you are not returning the list from the permuteword function. I believe you also need to remove calls to console.log. Once I did these two things I was able to get it to work with Cloudant using the following search queries (I also changed your hard-coded call with "african lion" back to doc.name):
default:"african"
default:"african lion"
default:"lion"
default:"lion african"
Here is the final script:
function(doc){
var list = [];
function permute(ss, used, res, level, list){
if(level==ss.length&&res!==""){
list.push(res);
return;
}
for(var i=0; i<ss.length; i++){
if (used[i]===true){
continue;
}
if(level>=0){
if (res!="" && list.indexOf(res)<0){
list.push(res.trim());
}
used[i]=true;
permute(ss, used, res+" "+ss[i], level+1, list)
used[i]=false;
}
}
}
function permuteword(s){
var ss=s.split(" ");
var used = [];
var res = "";
list = [];
permute(ss, used, res, 0, list);
return list;
}
if (doc.name) {
var contentIndex=permuteword(doc.name);
for(var i=0; i<contentIndex.length; i++){
index("default", contentIndex[i]);
}
}
}
Updated JSFiddle:
https://jsfiddle.net/14e7L3gw/1/
Original Answer
I believe there are issues with your Javascript. The permuteword function is not returning any results. See this JSFiddle:
https://jsfiddle.net/14e7L3gw/
Note: I added some logging and commented out the call to index. Run with your browser debugger to see the output.
Here is what is happening:
The first call to permuteword calls permute(["african","lion"], [], "", 0, []);
The first if in permuteword fails because level (0) != ss.length() (2) and res == "".
Then the function loops through ss, but never does anything because level = 0.
Ultimately permuteword returns an empty array, so nothing gets indexed.

Map/Reduce differences between Couchbase & CloudAnt

I've been playing around with Couchbase Server and now just tried replicating my local db to Cloudant, but am getting conflicting results for my map/reduce function pair to build a set of unique tags with their associated projects...
// map.js
function(doc) {
if (doc.tags) {
for(var t in doc.tags) {
emit(doc.tags[t], doc._id);
}
}
}
// reduce.js
function(key,values,rereduce) {
if (!rereduce) {
var res=[];
for(var v in values) {
res.push(values[v]);
}
return res;
} else {
return values.length;
}
}
In Cloudbase server this returns JSON like:
{"rows":[
{"key":"3d","value":["project1","project3","project8","project10"]},
{"key":"agents","value":["project2"]},
{"key":"fabrication","value":["project3","project5"]}
]}
That's exactly what I wanted & expected. However, the same query on the Cloudant replica, returns this:
{"rows":[
{"key":"3d","value":4},
{"key":"agents","value":1},
{"key":"fabrication","value":2}
]}
So it somehow only returns the length of the value array... Highly confusing & am grateful for any insights by some M&R ninjas... ;)
It looks like this is exactly the behavior you would expect given your reduce function. The key part is this:
else {
return values.length;
}
In Cloudant, rereduce is always called (since the reduce needs to span over multiple shards.) In this case, rereduce calls values.length, which will only return the length of the array.
I prefer to reduce/re-reduce implicitly rather than depending on the rereduce parameter.
function(doc) { // map
if (doc.tags) {
for(var t in doc.tags) {
emit(doc.tags[t], {id:doc._id, tag:doc.tags[t]});
}
}
}
Then reduce checks whether it is accumulating document ids from the identical tag, or whether it is just counting different tags.
function(keys, vals, rereduce) {
var initial_tag = vals[0].tag;
return vals.reduce(function(state, val) {
if(initial_tag && val.tag === initial_tag) {
// Accumulate ids which produced this tag.
var ids = state.ids;
if(!ids)
ids = [ state.id ]; // Build initial list from the state's id.
return { tag: val.tag,
, ids: ids.concat([val.id])
};
} else {
var state_count = state.ids ? state.ids.length : state;
var val_count = val.ids ? val.ids.length : val;
return state_count + val_count;
}
})
}
(I didn't test this code, but you get the idea. As long as the tag value is the same, it doesn't matter whether it's a reduce or rereduce. Once different tags start reducing together, it detects that because the tag value will change. So at that point just start accumulating.
I have used this trick before, although IMO it's rarely worth it.
Also in your specific case, this is a dangerous reduce function. You are building a wide list to see all the docs that have a tag. CouchDB likes tall lists, not fat lists. If you want to see all the docs that have a tag, you could map them.
for(var a = 0; a < doc.tags.length; a++) {
emit(doc.tags[a], doc._id);
}
Now you can query /db/_design/app/_view/docs_by_tag?key="3d" and you should get
{"total_rows":287,"offset":30,"rows":[
{"id":"project1","key":"3d","value":"project1"}
{"id":"project3","key":"3d","value":"project3"}
{"id":"project8","key":"3d","value":"project8"}
{"id":"project10","key":"3d","value":"project10"}
]}

Chrome Bookmarks API -

I'm attempting to create a simple example that would just alert the first 5 bookmark titles.
I took Google's example code and stripped out the search query to see if I could create a basic way to cycle through all Nodes. The following test code fails my alert test and I do not know why.
function dumpBookmarks() {
var bookmarkTreeNodes = chrome.bookmarks.getTree(
function(bookmarkTreeNodes) {
(dumpTreeNodes(bookmarkTreeNodes));
});
}
function dumpTreeNodes(bookmarkNodes) {
var i;
for (i = 0; i < 5; i++) {
(dumpNode(bookmarkNodes[i]));
}
}
function dumpNode(bookmarkNode) {
alert(bookmarkNode.title);
};
Just dump your bookmarkTreeNodes into the console and you will see right away what is the problem:
var bookmarkTreeNodes = chrome.bookmarks.getTree(
function(bookmarkTreeNodes) {
console.log(bookmarkTreeNodes);
});
}
(to access the console go to chrome://extensions/ and click on background.html link)
As you would see a returned tree contains one root element with empty title. You would need to traverse its children to get to the actual bookmarks.
Simple bookmark traversal (just goes through all nodes):
function traverseBookmarks(bookmarkTreeNodes) {
for(var i=0;i<bookmarkTreeNodes.length;i++) {
console.log(bookmarkTreeNodes[i].title, bookmarkTreeNodes[i].url ? bookmarkTreeNodes[i].url : "[Folder]");
if(bookmarkTreeNodes[i].children) {
traverseBookmarks(bookmarkTreeNodes[i].children);
}
}
}

Resources