I have data as follows in MongoDB,
ITEM DATA
{
id:1,
items: {3:'three', 4:'four'}
},
{
id:2,
items: {}
},
{
id:3,
items: {1:'one', 2:'two', 6:'six'}
},
{
id:4,
items: {1:'one', 2:'two', 'three'}
},
{
id:5,
items: {1:'one', 2:'two'}
},
{
id:6,
items: {1:'one'}
}
Also I have a map of items as follows locally,
ITEM MAP DATA
{
1:'one',
2:'two',
3:'three',
4:'four'
}
Lets say i need to insert {5: 'five'}, I need to insert 5 where there are two or many items from ITEM MAP DATA. the result should reflect something similar as follows,
ITEM DATA RESULT
{
id:1,
items: {3:'three', 4:'four', 5'five'}
},
{
id:2,
items: {}
},
{
id:3,
items: {1:'one', 2:'two', 6:'six'}
},
{
id:4,
items: {1:'one', 2:'two', 'three', 5:'five'}
},
{
id:5,
items: {1:'one', 2:'two', 5:'five'}
},
{
id:6,
items: {1:'one'}
}
I am very new to this field and following was my attempt to achieve this,
var dataItemMap = {};
dataItemMap['1']='one';
dataItemMap['2']='two';
dataItemMap['3']='three';
dataItemMap['4']='four';
var setObj = {};
DbConnector.getMutProConnection(function(err,db) {
setObj['5'] = 'five';
db.collection('itemData').update({
"$where": "return Object.keys(this.items).length > 1"
}, {$set: setObj}, {multi: true});
});
I came up with the above code by reading through this post: Mongodb Query based on number of fields in a record . But didn't seem to work and I dont know how to incorporate my second query.
I would be really grateful if you experts could provide me with code snippets, examples or references where I could achieve my requirement.
Thanks alot :)
Since there are no joins in MongoDB, you would have to design your schema to avoid the lookup to "Item Map" or else you would have to check that in memory in your program. Without that condition, the query could be as below.
db.item_data.update({ "$where": "return Object.keys(this.items).length > 1" }, {$set : {"items.5" : "five"}}, false, true)
Related
So I tried several ways, but I can't, I can modify several objects with the same key but I can't modify any with different keys, if anyone can help me is quite a complex problem
{
id: 123,
"infos": [
{ name: 'Joe', value: 'Disabled', id: 0 },
{ name: 'Adam', value: 'Enabled', id: 0 }
]
};
In my database I have a collection with an array and several objects inside which gives this.
I want to modify these objects, filter by their name and modify the value.
To give you a better example, my site returns me an object with the new data, and I want to modify the database object with the new object, without clearing the array, the name key never changes.
const object = [
{ name: 'Joe', value: 'Hey', id: 1 },
{ name: 'Adam', value: 'None', id: 1 }
];
for(const obj in object) {
Schema.findOneAndUpdate({ id: 123 }, {
$set: {
[`infos.${obj}.value`]: "Test"
}
})
}
This code works but it is not optimized, it makes several requests, I would like to do everything in one request, and also it doesn't update the id, only the value.
If anyone can help me that would be great, I've looked everywhere and can't find anything
My schema structure
new Schema({
id: { "type": String, "required": true, "unique": true },
infos: []
})
I use the $addToSet method to insert objects into the infos array
Try This :
db.collection.update({
id: 123,
},
{
$set: {
"infos.$[x].value": "Value",
"infos.$[x].name": "User"
}
},
{
arrayFilters: [
{
"x.id": {
$in: [
1
]
}
},
],
multi: true
})
The all positional $[] operator acts as a placeholder for all elements in the array field.
In $in you can use dynamic array of id.
Ex :
const ids = [1,2,..n]
db.collection.update(
//Same code as it is...
{
arrayFilters: [
{
"x.id": {
$in: ids
}
},
],
multi: true
})
MongoPlayGround Link : https://mongoplayground.net/p/Tuz831lkPqk
Maybe you look for something like this:
db.collection.update({},
{
$set: {
"infos.$[x].value": "test1",
"infos.$[x].id": 10,
"infos.$[y].value": "test2",
"infos.$[y].id": 20
}
},
{
arrayFilters: [
{
"x.name": "Adam"
},
{
"y.name": "Joe"
}
],
multi: true
})
Explained:
You define arrayFilters for all names in objects you have and update the values & id in all documents ...
playground
I have a multidimensional javascript array of objects that I am trying to use to simply collate the Unit id into a new array as shown below.
What is the best solution for returning the id within the inner value so I just get an array of the ids whatever I try seems to not work
[
{
units: [
{
id: 10000282,
name: "Group 1",
},
{
id: 10000340,
name: "Group 2",
},
{
id: 10000341,
name: "Group 3",
},
],
},
{
units: [
{
id: 10000334,
name: "Group 4",
},
],
},
]
Expected output - just return an array with simply the ids
e.g
ids = [ 10000282, 10000340, 10000341, 10000334 ]
Assuming that data is in variable data:
> data.map(o => o.units.map(u => u.id)).flat()
[ 10000282, 10000340, 10000341, 10000334 ]
This assumes you're in an environment where .flat() is a thing.
If that's not the case, the longer way around is
const ids = [];
data.forEach(o => {
o.units.forEach(u => {
ids.push(u.id);
});
});
Any help would be appreciated !! I couldn't find an answer.
Given input facts to the engine such as -
const facts = {
cart: {
prop1: true,
prop2: "My Cart",
prop3: {
prop4: "North America"
},
products: [
{
category: 1,
classification: null
},
{
category: 2,
classification: null
},
{
category: 1,
classification: null
}
]
}
};
I want to be able to process each object in the products array and define a separate rule for each category and set the classification field for that category.
Something like -
let condition1 = {
all: [
{
fact: 'category',
operator: 'equal',
value: 1
}
]
};
let condition2 = {
all: [
{
fact: 'category',
operator: 'equal',
value: 2
}
]
};
let event1 = {
type: 'category 1 event'
// Update classification
};
let event2 = {
type: 'category 2 event'
// Update classification
};
How do I do this? Do i set the classification field in the event handler for that event? How do I access the object the category belongs to?
I tried using the below, but it selects all the category values from each object. I want to be able to process each object separately.
let condition = {
all: [
{
fact: 'cart',
operator: 'contains',
value: 1,
path: '$.products[*].category'
}
]
}
I cant add them as runTime facts either since you can have only 1 runtime fact and its value. (No Duplicates)
Hola Developers im trying to create a product in my shopping card , but still im stacked in one issue :
Can't find the proper way to design a object just on the same way i receive it from my json (back-end).
Lets say the part is causing the issue is this:
JSON RECEIVED
"product_category": [
{
"categories_of_product": "Good"
},
{
"categories_of_product": "Danger"
},
{
"categories_of_product": "Homer"
}
],
"people_buying_this_product": "Jack Ripper"
},
]
then on my building-product-processs , on the data return is a section that have to do with this, where in then using checkboxes i get which checkbox is checked or not , in order to build a array of categories similar to the former one i have shown:
DATA RETURN
ProductAdded: {
description: "",
upload_image3: "",
upload_image2: "",
upload_image1: "",
unities: 0,
price: 0,
name: "",
Categories: [
{ id: 1, value: "Miscellaneous", selected: false },
{ id: 2, value: "Homer", selected: false },
{ id: 3, value: "Electronic", selected: false },
{ id: 4, value: "Internet", selected: true },
{ id: 5, value: "Kids", selected: false },
{ id: 6, value: "Donas", selected: true },
{ id: 7, value: "Sports", selected: true },
{ id: 8, value: "Horror", selected: false }
],
METHOD that dispatches de action in vuex
addProductOnSale(thisCurrent) {
this.$store.dispatch("addProductSale", this.ProductAdded);
}
then being already in the VUEX state management , on the action in fact , trying to build the new product for this product category, i set this:
addProductSale({commit,getters},currentProduct){
product_category: currentProduct.Categories.filter(option =>
option.selected).map(option => {categories_of_product: option.value})
}
------------------->this one gives me undefined like:
"product_category":
[
undefined
],
"product_category":
[
undefined
],
"product_category":
[
undefined
],
]
or tried this other :
addProductSale({commit,getters},currentProduct){
product_category:currentProduct.Categories.forEach( option.selected,() =>
option.value).map(option => option.selected),...
}
and gave me error , not even showing a result.
Basically cant find the way to design the same structure im receiving for json , nor even reaching to values.
Is weird ,but if i only set the query like this:
addProductSale({commit,getters},currentProduct){
product_category:currentProduct.Categories.filter(option => option.selected)
}
Indeed filters and gives back the objects inside Categories which commit the condition of selected true , but with its plain format just as the data returns , but that's not the idea.
Any advice or help?
Thanks in advance!!!!
I am trying to update a nested value of an object using the spread operator. This is my first time using this and I believe I am pretty close to achieving my end goal but I just can't seem to figure out what I actually need to do next.
I have an array which is structured like this:
[
{
name: "Category 1",
posts: [
{
id: 1,
published: false,
category: "Category 1"
},
{
id: 2,
published: true,
category: "Category 1"
}
]
},
{
name: "Category 2",
posts: [
{
id: 3,
published: true,
category: "Category 2"
},
{
id: 4,
published: true,
category: "Category 2"
}
]
}
]
On the click of a button I am trying to update the published value, and as I am using React I need to set the state. So it got recommended to me that I update using the spread operator.
onPostClick(post) {
post.pubished = !post.published;
this.setState({...this.state.posts[post.category], post})
}
If I log out the result of {...this.state.posts[post.category], post} I can see that the published is getting added to the parent which forms:
{
name: "Category 1",
published: false,
posts: [
...
]
}
Obviously this isn't the intended result, I want it to update the actual object within the posts object.
I have tried to do something like this.setState({...this.state.posts[post.category].posts, post}) but I get a message that it is undefined.
You can't access your data with this.state.posts[post.category]. posts data in the objects of the array.
You can make a filter to find your category object in array and change its posts value.
onPostClick(post) {
//CLONE YOUR DATA
var postArray = this.state.posts;
//FIND YOUR CATEGORY OBJECT IN ARRAY
var categoryIndex = postArray.findIndex(function(obj){
return obj.name === post.category;
});
//FIND YOUR POST AND CHANGE PUBLISHED VALUE
postArray[categoryIndex].posts.forEach(function(item){
if (item.id === post.id) {
item.published = !item.published;
}
});
//SET TO STATE TO RERENDER
this.setState({ posts: postArray});
}
This should work if your name of the state is true.
just adding, we know there are many ways to succeed, maybe you also want to try this way too..
onPostClick = post => {
let published = this.state.data.map((item, i) => {
item.posts.map((item_post, i) => {
if (item_post.category === post.category) {
item_post.published = !post.published;
}
});
});
this.setState({ ...this.state.data, published });
};