I would like to remove all key/value pairs where the key is url from all documents inside a mongodb collection.
I've been agonising over this all weekend and have only managed to partially solve it using $unset, but I'm struggling to access all items particularly key/values inside objects in arrayKey and also do it in one query/function (if possible).
This is generally how each document looks. There sometimes may be more objects in the arrayKey, but other than that they're pretty similar:
{
"keyOne": "String",
"keyTwo": 7,
"keyThree": {
"subKeyOne": "String",
"url": "String"
},
"arrayKey": [
{
"arrayKeyOne":"String",
"url": "String"
},
{
"arrayKeyOne":"String",
"url": "String"
}
],
"url":"String"
}
Any help would be greatly appreciated. I'm still new to programming and mongodb so the documentation is a bit dense for a beginner.
Thanks :)
Related
I am very new to coding, so my apologies if I use the wrong terms or am unclear. I have a list of 400+ words I need to be able to enter into my database. I found this collection to loop through my data and post it to the database. I am able to mostly get it to work, except for this one section (the meanings section) where it's an array of objects. If it makes a difference, this is for a React project and using MongoDB for the database.
Each word looks like this:
{
"text": "happy",
"traits": [
"wordlist100"
],
"meanings": [
{
"meaning": "happy",
"category": "default"
}
],
"approved": true,
"createdby": "60dcd7ba69b1e52ac8138051",
"approvedBy": "60dcd7ba69b1e52ac8138051",
"lastUserEdit": "60dcd7ba69b1e52ac8138051",
"blocked": false
}
Where each word can have multiple traits and multiple meanings.
I have all the words in a JSON file, and am running it through Postman using the collection linked above. This is the body of my request in Postman:
{
"text": "{{text}}",
"traits": [
"{{traits}}"
],
"meanings": [
{
"meaning": "{{meaning}}",
"category": "{{category}}"
}
],
"approved": true,
"createdby": "60dcd7ba69b1e52ac8138051",
"approvedBy": "60dcd7ba69b1e52ac8138051",
"lastUserEdit": "60dcd7ba69b1e52ac8138051",
"blocked": false
}
Using this, everything comes through correctly in my database except for the meaning and category of a word. This is what shows up in MongoDB:
{
"_id": {"$oid": "6121bd6addff936ba4eb84bf"},
"traits": [
"wordlist100"
],
"text": "happy",
"meanings": [
{
"_id": {"$oid": "6121bd6addff936ba4eb84c0"},
"meaning": "{{meaning}}",
"category": "{{category}}"
}
],
"approved": true,
"createdBy": {"$oid": "60dcd7ba69b1e52ac8138051"},
"approvedBy": {"$oid": "60dcd7ba69b1e52ac8138051"},
"lastUserEdit": {"$oid": "60dcd7ba69b1e52ac8138051"},
"blocked": false,
"createdAt": {"$date": "2021-08-22T02:58:50.679Z"},
"updatedAt": {"$date": "2021-08-22T02:58:50.679Z"},
"__v": 0
}
What am I doing wrong with the meanings section of the word? I tried playing around with several combinations of brackets and such for how to set up the meanings part.
I did try:
"meanings": [
"{{meanings}}"
]
...but that didn't work at all. Most of what I tried created an error that stopped the collection from running at all (it was probably bad syntax, as I said, I'm really new). This is the only arrangement that seems to get me close to right. Any help would be greatly appreciated.
Thanks!!
Attaching pics of the Postman code and created MongoDB document if it's easier for any of you to look at it with that formatting:
Image of Postman code
Image of MongoDB document created
So I feel foolish and this just shows how new I am to all of this. When I posted this question, all I had done was to try copying the style of what I saw in the body text of the example I found (linked in my question), but didn't do anything with actually defining variables or touching the pre-request script because I didn't realize that was a separate step. So basically, I just got lucky that it was smart enough to figure out the other values without me defining them as variables.
If anyone is reading this later, here's 3 pages of documentation I used to help me figure out my errors: Using Variables, Importing Data Files, and Scripting in Postman.
From reading those, I added the following code in the pre-request script:
let meanings = pm.iterationData.get("meanings");
pm.variables.set("meaning", meanings[0].meaning);
pm.variables.set("category", meanings[0].category);
I also set "meaning" and "category" as named variables with no initial value in the collection.
Image of adding variables to the Postman collection
One caveat I should note is that I'm not certain how well this will work once I start entering stuff with more than one trait or more than one meaning, because I haven't tested those parts yet. I suspect I still need to tweak things to make it work under those instances. But it is working in the examples I have with just one trait and one object in the meanings array.
I'm working on a Flutter "Collections" app where I want a user to be able to define a schema for their list, then create several items that conform to that schema.
{
"name": "My Book Collection",
"schema": [
{
"id": "uuid-title",
"type": "text",
"name": "Title",
"unique": true
},
{
"id": "uuid-pages",
"type": "number",
"name": "Pages",
"min": 0,
"max": null,
"format": "int"
}
],
"items": {
"abc-123": {
"uuid-title": "The Hobbit",
"uuid-pages": 304
},
"def-456": {
"uuid-title": "Harry Potter and the Philosopher's Stone",
"uuid-pages": 223
}
}
}
What strategies can I use to update Specific Items or Schema Items, preferable immutably? I'm thinking I can make a Collection which has a List<SchemaItem> and Map<String, CollectionItem>. I think I can use a Provider or ProxyProvider to provide the List<SchemaItem> and a "Selected" CollectionItem to downstream widgets.
What strategies to I use to update items:
Is it enough to implement a CollectionItem.copyWith() function with some ChangeNotifier?
Do I need to go higher, with a Collection.updateItem(id: "abc-123", { "uuid-pages": 365 }) and wait for a Stream somewhere to provide an updated object?
Do I jump all the way to the top with a Service? CollectionService.selectedCollection.updateItem(id: "abc-123", { "uuid-pages": 365 }) and wait for a sqflite or Firebase update to trigger a rebuild?
I'm open to any starting points. All the tutorials, guides, and videos I've seen work with very simple data. Counters (Ints), ToDos (Strings & Bools), Pizza Toppings (List), but nothing with these nested maps. Do I just need to spend more time getting comfortable with OOP?
Finally, would I be crazy to work with the data as maps or should I definitely be converting them to Classes?
just activate the robo pojo generator in your android studio and past this json schema and get the corresponding model class and use it as you want
I've been trying to become familiar with using MongoDB, particularly GridFS (which is implemented through the client). In a project I'm playing around with, I have users with corresponding locations, followed by corresponding data, but it is currently just stored on a filesystem which will ultimately lead to problems.
So an example data structure I have now is:
./(userId)/images/img1.png
./(userId)/data/sensor1/sensorOutput1.data
./(userId)/data/sensor1/sensorOutput2.data
./(userId)/data/sensor2/sensorOutput1.data
./(userId)/data/sensor2/sensorOutput2.data
So, in looking at GridFS, I see that you can pass attribute/values to be associated with the meta-data for each file. Looking at this setup and after reading tutorials on MongoDB, I thought of this approach:
Have one database with multiple collections (such as data or images just to separate some of the data). Then in each of the collections, have attributes for each document such as:
Under image collection:
{
"userId": 5,
"path": "",
"filename":"img1.png"
...
}
or
Under data collection:
{
"userId": 5,
"path": "sensor1",
"filename": "sensorOutput1.data"
...
}
Alternatively, I could just have a collection, and for the sake of this example, I'll call "Everything"
{
"userId": 5,
"path": "images/",
"filename": "img1.png"
...
}
{
"userId": 5,
"path": "data/sensor1/",
"filename": "sensorOutput1.data"
...
}
{
"userId": 5,
"path": "data/sensor2/",
"filename": "sensorOutput1.data"
...
}
Do either of these solutions seem reasonable? Would I then create an index on the "path" attribute? I've seen examples for adding files to MongoDB just haven't found one with how to structure user files.
Thanks!
I want to store website menus in Mongo for the navigation of my CMS, but since I'm new to Mongo and the concept of documents, I'm trying to figure out what would be best:
a) Should I store menu documents, containing children and those having more children, or
b) Should I store menu item documents with parent_id and child_ids ?
Both would appear to have benefits, since in case A it's normal to load an entire menu at once as you'll need everything to display, but B might be easier to update single items?
I'm using Spring data mongo.
PS: If I asked this question in a wrong way, please let me know. I'm sure this question can be expanded to any general parent-child relationship, but I was having trouble finding the right words.
Since menus are typically going to be very small (under 16MB I hope) then the embedded form should give you the best performance:
{
"topItem1": [
{ "name": "item1", "link": "linkValue" },
{ "name": "item2", "link": "linkValue" }
],
"topItem2": [
{ "name": "item1", "link": "linkValue" },
{ "name": "item2", "link": "linkValue" }
{
"name": "sub-menu",
"type": "sub",
"items": [
{ "name": "item1", "link": "linkValue" },
{ "name": "item2", "link": "linkValue" }
}
}
]
}
The only possible issue there is with updating the content inside nested arrays, as MngoDB can only "match" the first found array index. See the positional $ operator documentation for this.
But as long as you know the positions then this should not be a problem, using "dot notation" concepts:
db.menu.update({}, {
"$set": {
"topItem2.2.items.1": { "name": "item3", "link": "linkValue" }
}
})
But general adding should be simple:
db.menu.update(
{ "topItem2.name": "sub-menu" },
{
"$push": {
"topItem2.2.items": { "name": "item4", "link": "linkValue" }
}
}
)
So that is a perspective on how to use the inherrent embedded structure rather than associate "parent" and "child" items.
After long hard thinking I believe I would use:
{
_id: {},
submenu1: [
{label: "Whatever", url: "http://localhost/whatever"}
]
}
I thought about using related documents with IDs all sitting in a collection but then you would have to shoot off multiple queries to get the parent and its range, possibly even sub-sub ranges too. With this structure you have only one query for all.
This structure is not infallible however, if you change your menu items regularly you might start to notice fragmentation. You can remedy this a little with powerof2sizes allocation: http://docs.mongodb.org/manual/reference/command/collMod/#usePowerOf2Sizes
But yes, with careful planning you should be able to use one single document for every parent menu item
Is this example of nesting generally accepted as good or bad practice (and why)?
A collection called users:
user
basic
name : value
url : value
contact
email
primary : value
secondary : value
address
en-gb
address : value
city : value
state : value
postalcode : value
country : value
es
address : value
city : value
state : value
postalcode : value
country : value
Edit: From the answers in this post I've updated the schema applying the following rules (the data is slightly different from above):
Nest, but only one level deep
Remove unneccesary keys
Make use of arrays to make objects more flexible
{
"_id": ObjectId("4d67965255541fa164000001"),
"name": {
"0": {
"name": "Joe Bloggs",
"il8n": "en"
}
},
"type": "musician",
"url": {
"0": {
"name": "joebloggs",
"il8n": "en"
}
},
"tags": {
"0": {
"name": "guitar",
"points": 3,
"il8n": "en"
}
},
"email": {
"0": {
"address": "joe.bloggs#example.com",
"name": "default",
"primary": 1,
"il8n": "en"
}
},
"updates": {
"0": {
"type": "news",
"il8n": "en"
}
},
"address": {
"0": {
"address": "1 Some street",
"city": "Somecity",
"state": "Somestate",
"postalcode": "SOM STR",
"country": "UK",
"lat": 49.4257641,
"lng": -0.0698241,
"primary": 1,
"il8n": "en"
}
},
"phone": {
"0": {
"number": "+44 (0)123 4567 890",
"name": "Home",
"primary": 1,
"il8n": "en"
},
"1": {
"number": "+44 (0)098 7654 321",
"name": "Mobile",
"il8n": "en"
}
}
}
Thanks!
In my opinion above schema not 'generally accepted', but looks like great. But i suggest some improvements thats will help you to query on your document in future:
User
Name
Url
Emails {email, emailType(primary, secondary)}
Addresses{address, city, state, postalcode, country, language}
Nesting is always good, but two or three level nesting deep can create additional troubles in quering/updating.
Hope my suggestions will help you make right choice of schema design.
You may want to take a look at schema design in MongoDB, and specifically the advice on embedding vs. references.
Embedding is preferred as "Data is then colocated on disk; client-server turnarounds to the database are eliminated". If the parent object is in RAM, then access to the nested objects will always be fast.
In my experience, I've never found any "best practices" for what a MongoDB record actually looks like. The question to really answer is, "Does this MongoDB schema allow me to do what I need to do?"
For example, if you had a list of addresses and needed to update one of them, it'd be a pain since you'd need to iterate through all of them or know which position a particular address was located. You're safe from that since there is a key-value for each address.
However, I'd say nix the basic and contact keys. What do these really give you? If you index name, it'd be basic.name rather than just name. AFAIK, there are some performance impacts to long vs. short key names.
Keep it simple enough to do what you need to do. Try something out and iterate on it...you won't get it right the first time, but the nice thing about mongo is that it's relatively easy to rework your schema as you go.
That is acceptable practice. There are some problems with nesting an array inside of an array. See SERVER-831 for one example. However, you don't seem to be using arrays in your collection at all.
Conversely, if you were to break this up into multiple collections, you would have to deal with a lack of transactions and the resulting race conditions in your data access code.