How to re-map the fields of a mongodb collection? - mongodb

Picture it -- I have a collection, and it has a particular mapping.
Pretend:
{
"field": "lala",
"subdoc": {
"otherfield": "la",
"etcfield": "la"
}
}
And I need to convert that to a different data structure:
{
"field-gets-renamed": "lala",
"subdoc-has-different-stuff-in-it": {
"something": "la",
"something-else": "la"
}
}
What is the typical way of doing that? (Is there one?)
Do I read collection1 doc by doc and write it to a different collection?
Or is there a way to just remap the fields in collection1?
I would greatly appreciate some example, as I am a novice to mongodb.

You should make use of the $rename operator
In your case it would be:
db.collectionName.update({}, { $rename : { 'field' : 'field123', 'subdoc' : 'subdoc123', 'subdoc.otherfield' : 'subdoc.otherfield123', 'subdoc.etcfield' : 'subdoc.etcfield123'} }, false, true);
P.S: I havent tested the above command.

Related

Pymongo: find_one_and_update or update_one based on "custom" _id Object

this is the way one document looks like:
{
"_id" : ObjectId("5ebe67974bfaadfe0ec3ed10"),
"date" : 20180101,
"likelybuy" : 1000614,
"bixdemo_alter" : 2,
"bixdemo_bundesland" : 10,
"caseid" : 653433802,
"bixdemo_haushalts_nettoeinkommen" : 2.0,
"bixdemo_geschlecht" : 1,
"sector" : 1026,
}
coll.update_one({'_id': id},
{
'$set': {
'sector': 1029,
}
})
I can not use the "id_" to find the correct document, I have to use a combination of "date", "caseid" and "sector"
Is there a way to do this?
You can directly match the id, instead of matching all other field's value. You can do the following:
Import ObjectId:
from bson.objectid import ObjectId`
Do the query like:
coll.update_one({'_id': ObjectId(id)},
{
'$set': {
'sector': 1029,
}
})
I hope this works for you.
Sure; you don't have to use an _id as a filter, you can use any fields. Just use those fields in the filter, e.g.
coll.update_one({'date': 20180101, 'caseid': 653433802,'sector': 1026},
{
'$set': {
'sector': 1029,
}
})
first of all, I think you tried to find your id like:
coll.update_one({_id:'12314'},{})
but the problem is you pass string to search objectid.So, mongodb can not find it. If you try this below:
coll.update_one({_id:mongoose.Types.ObjectId('12314')},{})
It will work I think and also for combination search you can use '$elemMatch' in mongodb.

Can elastic search provide nested json results?

I know that elastic search provides good support for nested json. It has very good support for nested objects with advance indexing.
So, when I make a nested query in elastic search, can the query result be obtained in original nested form ? Or is the query result in flattened form like that in lucene or solr ?
Note: I have used apache solr and lucene before. And, I am evaluating other different search platforms for better support for nested json objects.
I'm giving you a simple example of results maintaining the depth.
PUT people { "mappings": {
"list": {
"properties": {
"name": {
"type": "nested"
}
}
} } }
PUT people/list/1 { "age" : "19", "name" : [
{
"first" : "John",
"last" : "Smith"
} ] }
PUT people/list/2 { "age" : "23", "name" : [
{
"first" : "Wilber",
"last" : "Smith"
} ] }
GET people/list/_search { "query": {
"match_all": {} } }
As far as I understand, you'll prefer nested mapping to object mapping. Because object would flatten results. See this for reference:
https://www.elastic.co/guide/en/elasticsearch/reference/2.4/nested.html

How to update nested object in mongodb

I am rather new to mongodb and self learning. Since recently I am a bit stuck on this one. I would like to update a nested document. I worked around it by retrieving the full document and updating the entire thing, but I need a solution where I can update in a single shot. I made the following simplified example:
db.test.insert({
'name': 'someSchool',
'classes': [
{
'name': 'someClass',
'students': [
{
'name': 'Jack',
'coolness' : 7
}
]
}
]
});
Here the arrays only have one entry for simplicity, you understand we normally have more...
db.test.find({
'name' : 'someSchool',
'classes' : {
$elemMatch: {
'name': 'someClass',
'students.name' : 'Jack'
}
}
});
This find works! Thats great, so now I want to use it in an update, which is where Im stuck. Something like this??
db.test.update({
'name' : 'someSchool',
'classes' : {
$elemMatch: {
'name': 'someClass',
'students.name' : 'Jack'
}
}
}, {
'$set' : { 'classes.students.coolness' : 9}
});
So this doesnt work and now I am stuck at it :) Hopefully someone here can help.
Side note: I am using mongoose. If you guys tell me its better to change the schema to make it easier somehow, I can.
Update since marked as duplicate: In the referenced question, there is only 1 level of nesting and the problem gets solved by using dot notation. Here there are 2 levels. I accepted teh answer which explains it is not supported and which gives a correct workaround.
As mentioned here it's not possible right now to update two level nested arrays.
I would suggest you to change your schema in order to replace one level array nesting with object. So your document would look like this:
{
"name" : "someSchool",
"classes" : {
"someClass" : {
"students" : [
{
"name" : "Jack",
"coolness" : 7
}
]
}
}
}
Then you can use positional operator to update specific array element. But be aware that positional operator updates only the first element in array that matches the query.
Update query would look like this:
db.test.update({
'classes.someClass.students' : {
$elemMatch: {
'name' : 'Jack'
}
}
}, {
'$set' : {
'classes.someClass.students.$.coolness' : 9
}
});

How to query complex structures in MongoDB?

I persist my Python classes to JSON and write them to MongoDB. I'm using a JSON Encoder which has been presented here. This results in a slight complex JSON structure which does not follow the simple "string" key/values in all the MongoDB tutorials. Here is an excerpt of a class written to JSON:
{
"_id" : ObjectId("51f2397c86a49a5e6dec4633"),
"__module__" : "experiment.experimentmanager",
"experiments" : {
"FOO" : [
{
"__module__" : "experiment.experiment",
"enable_routing_table_trace" : false,
"__class__" : "Experiment",
"scenario_name" : "foobar",
"enable_network_visualize" : false
},
}
I'm wondering how I could check for example if there is a key "FOO" in experiments using MongoDBs find? Thanks in advance!
To check if field exists use$exists operator.
To access complex structures use dot notation. For example:
db.inventory.find( { "experiments.FOO": { $exists: true} } )
This query should work:
db.collection.find({
"experiments.FOO": {
$exists:true
}
});

How do I perform this query in both Mongo console and Mongoid?

I'm trying to learn how to query Mongo in more advanced ways. Let's say my data structure is this:
{ "_id" : "-bcktick-ajman-ae-292932", "asciiname" : "`Ajman",
"alternatenames" : [
{
"isolanguage" : "no",
"alternateNameId" : 2698358,
"alternateName" : "Ajman"
},
{
"isolanguage" : "en",
"alternateNameId" : 2698357,
"alternateName" : "Ajman"
}
]
}
So to find Ajman is easy:
db.cities.find({ "asciiname":"`Ajman" })
However, I want to find cities that only have an isolanguage of en. You'll notice the isolanguage is in the alternatenames array.
But I can't seem to find the correct syntax in either the client or mongoid
Either one (or both) would be greatly appreciated.
Thanks
I think you are looking for the $elemMatch keyword:
db.cities.find(
{ 'alternatenames' : {
$elemMatch: { isolanguage: 'en'}
}
})
Currently, Mongoid does not have a helper for $elemMatch so you have to pass in the raw query:
City.where({ :alternatenames => { '$elemMatch' => { :isolanguage => 'en' } } })
More info here on $elemMatch here:
http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24elemMatch
http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29
More info on Mongoid support for $elemMatch here:
http://groups.google.com/group/mongoid/browse_thread/thread/8648b451e3957e12
https://github.com/mongoid/mongoid/issues/750