MongoDB converting an array to dictionary - mongodb

I insert:
{
...
"loc":[-124.9973,49.68829]
...
}
and it is stored as:
"loc": {
"0": -124.9973,
"1": 49.68829
}
This occurs from mongo command line or via PHP or through RockMongo forms.
Is this the expected behavior?

When I do an insert from the mongo shell I DO NOT get that behavior
dmReplSet:PRIMARY> db.aug29.insert( { "loc" : [ -124.9973, 49.68829 ] } );
WriteResult({ "nInserted" : 1 })
dmReplSet:PRIMARY> db.aug29.find();
{ "_id" : ObjectId("54010c47de66cda372635186"), "loc" : [ -124.9973, 49.68829 ] }
dmReplSet:PRIMARY> db.aug29.find().pretty()
{
"_id" : ObjectId("54010c47de66cda372635186"),
"loc" : [
-124.9973,
49.68829
]
}
dmReplSet:PRIMARY>
How exactly are you doing your insert? Is it through some OR mapping?
On the other hand, if you are trying to do geospacial stuff in MongoDB you probably should read up on it and be aware it has been evolving and is MongoDB version specific ( http://blog.mongolab.com/2014/08/a-primer-on-geospatial-data-and-mongodb/ and http://myadventuresincoding.wordpress.com/2011/10/02/mongodb-geospatial-queries/ ).

Related

Update: Move field into another's field array

I'm not 100% percent if this is possible, but i think it should be.
I want to update a document so that a field (END) is inserted into an array (INTERMISSIONS). I think im quite close to achieving it, but i either get an error or insert the string "$END".
The two queries i have are :
db.myCollection.findOneAndUpdate(
{"_id" : new ObjectId("...")},
{ '$push' : {'INTERMISSIONS' : '$END' } }
)
This one completes without errors, but instead of the $END value just "$END" is inserted
db.myCollection.findOneAndUpdate(
{"_id" : new ObjectId("...")},
{ '$push' :
{'INTERMISSIONS' : {$first:"$END" }}
}
)
Here i tried to "force" mongo to recognise $END as a field, but i instead get the error The dollar ($) prefixed field '$first' in 'INTERMISSIONS..START.$first' is not valid for storage.
The document structure is the following
{
"_id" : ObjectId("5f7dabb9c02c0000d2003ec2"),
"USUARIO" : "admin",
"START" : ISODate("2020-10-07T11:51:21Z"),
"INTERMISSIONS" : [ ],
"END" : ISODate("2020-10-08T09:39:27Z")
}
When you use an operator check if it can take as argument an expression,
like here a field reference.
{ $push: { <field1>: <value1>, ... } }
MongoDB can do much more,with mongodb >= 4.2 you can do updates using the aggregation pipeline.
I give you the command,the "q" is the query,the "u" is the update pipeline,
you can use it with any driver that supports mongodb >= 4.2
> use testdb
switched to db testdb
> db.testcoll.drop()
true
> db.testcoll.insert(
... {
... "_id" : "5f7dabb9c02c0000d2003ec2",
... "USUARIO" : "admin",
... "START" :ISODate("2020-10-07T11:51:21Z"),
... "INTERMISSIONS" : [ ],
... "END" : ISODate("2020-10-08T09:39:27Z")
... }
... )
WriteResult({ "nInserted" : 1 })
> db.runCommand(
... {
... "update": "testcoll",
... "updates": [
... {
... "q": {},
... "u": [
... {
... "$addFields": {
... "INTERMISSIONS": {
... "$concatArrays": [
... "$INTERMISSIONS",
... [
... "$END" //or use {"start" : "$END"},anything you want to add
... ]
... ]
... }
... }
... }
... ],
... "multi": false
... }
... ]
... }
... )
{ "n" : 1, "nModified" : 1, "ok" : 1 }
> db.testcoll.find({}).pretty();
{
"_id" : "5f7dabb9c02c0000d2003ec2",
"USUARIO" : "admin",
"START" : ISODate("2020-10-07T11:51:21Z"),
"INTERMISSIONS" : [
ISODate("2020-10-08T09:39:27Z")
],
"END" : ISODate("2020-10-08T09:39:27Z")
}

query to convert mongodb array to key value pair

i need to create a mongodb query to convert an array into key-value
my document is like this:
{
"_id" : ObjectId("5c8718b9b5fe262104408374"),
"axis" : "x",
"message_time" : ISODate("2019-03-11T08:04:41.000Z"),
"x_axis" : [
0.9766,
1.9531,
2.9297,
3.9063,
4.8828,
5.8594,
6.8359,
7.8125,
8.7891,
],
"etl_date_time" : ISODate("2019-03-12T02:26:01.510Z")
}
i want to convert it to
{
"_id" : ObjectId("5c8718b9b5fe262104408374"),
"axis" : "x",
"message_time" : ISODate("2019-03-11T08:04:41.000Z"),
"x_axis" : 8.7891,
"etl_date_time" : ISODate("2019-03-12T02:26:01.510Z")
}
can anyone help me with the query?
You can use aggreggation framework to achieve this.
db.collection.aggregate([
{
$addFields: {
x_axis: {
$arrayElemAt: [
{
$slice: [
"$x_axis",
-1
]
},
0
]
}
}
}
])
If you need to perform an update on your collection, you can add an $out stage
Mongo playground

Using embedded documents in spring data aggregation

I have a MongoDB document like this example doc:
{
"_id" : "A",
"articleNumber" : "0123456",
"shopDependentProperties" :
{
"shop" : "DE",
"foo" : "foo",
"bar" : "bar"
}
}
and want to pull out the properties of shopDependentProperties, to have the following result
{
"_id" : "A",
"articleNumber" : "0123456",
"foo" : "foo",
"bar" : "bar"
}
In MongoDB Shell i can solve it this way:
db.test.aggregate(
[
{
$project:
{
_id : "$_id",
articleNumber : "$articleNumber",
foo:"$shopDependentProperties.foo",
bar:"$shopDependentProperties.bar"
}
}
]
)
But: In Spring Data MongoDB i can't extract the embedded document contents.
I tried many combinations, nothing worked. For example:
ProjectionOperation projection = Aggregation.project("_id");
projection.andExpression("shopDependentProperties.foo").as("foo");
projection.andExpression("shopDependentProperties.bar").as("bar");
System.out.println(projection.toDBObject(Aggregation.DEFAULT_CONTEXT));
will ignore the shopDependentProperties.shop stuff and just print out
{ "$project" : { "_id" : 1}}
Any suggestions?
Thx
Haven't tested this, but as of
http://docs.mongodb.org/manual/reference/operator/aggregation/project/
you specify included / excluded fields like this:
db.test.aggregate(
[
{
$project:
{
_id : "$_id",
articleNumber : 1,
"shopDependentProperties.foo": 1,
"shopDependentProperties.bar": 1
}
}
]
)
Further down they explain, how to include embedded documents in the projection result.
I know how to do it in MongoDB, the problem was about doing the same thing in Spring Data.
But it works the same way, why didn't I try that before?
Solution:
ProjectionOperation projection = Aggregation.project(
"brandName",
"$shopDependentProperties.foo",
"$shopDependentProperties.bar" );

Push and slice multiple times in MongoDB

I'm trying to do a push a new value to a capped array:
db.messages.insert({name:"test1"})
db.messages.update({name:"test1"}, {"$push":{"output": {"$each": ["test1"], "$slice": -10}}})
db.messages.update({name:"test1"}, {"$push":{"output": {"$each": ["test2"], "$slice": -10}}})
So, the first time I execute the update, I get what I expect:
{
"_id" : ObjectId("51d482ee7252cb3f7eb81ac1"),
"name" : "test1",
"output" : [
"test1"
]
}
But, after the second update, I get the following:
{
"_id" : ObjectId("51d482ee7252cb3f7eb81ac1"),
"name" : "test1",
"output" : [
"test1",
{
"$each" : [
"test2"
],
"$slice" : -10
}
]
}
When I expected the following:
{
"_id" : ObjectId("51d482ee7252cb3f7eb81ac1"),
"name" : "test1",
"output" : [
"test1",
"test2"
]
}
Probably I'm not understanding how to use $push with $slice, but looking at the documentation I couldn't figure out what I'm doing wrong. How can achive adding a new element to a capped array?
The behavior you observed can be reproduced in MongoDB version 2.2. Your example works as expected in MongoDB version 2.4
> db.things.insert({name:"test1"})
> db.things.update({name:"test1"}, {"$push":{"output": {"$each": ["test1"], "$slice": -10}}})
> db.things.find()
{ "_id" : ObjectId("51d489f730d17c1ffbd6ff9f"), "name" : "test1", "output" : [ "test1" ] }
> db.things.update({name:"test1"}, {"$push":{"output": {"$each": ["test2"], "$slice": -10}}})
> db.things.find()
{ "_id" : ObjectId("51d489f730d17c1ffbd6ff9f"), "name" : "test1", "output" : [ "test1", "test2" ] }
From the documentation, $each support to $push operator was added in version 2.4
http://docs.mongodb.org/manual/reference/operator/each/#op._S_each
Most likely you are using an older version of MongoDB that does not support $each with the $push operator. What version of MongoDB are you running? You can find out the version you are running by using the following command from MongoDB shell.
>db.version()
To get the latest release of MongoDB, please go to the following link.
http://www.mongodb.org/downloads

mongo - how to query a nested json

I am a complete mongo newbie. I am using mongo hub for mac. I need to query the for following json -
{ "_id" : ObjectId( "abcd" ),
"className" : "com.myUser",
"reg" : 12345,
"test" : [
{ "className" : "com.abc",
"testid" : "pqrs" } ] }
and find records where testid is pqrs. How would I go about doing that?
You can type {'test.testid': 'pqrs'} in the query field of Mongo Hub.
Looks like test is an array. If you are expecting multiple values in array you can do -
"test": {
"$elemMatch": {
"testid": "pqrs",
}
}