3

Working with mongolite v0.9.1 (R) and MongoDB v3.4, I'd like to join two collections, the first one, the parent containing an ObjectId, the second one, the children containing the string value of the parents' ObjectId.

This is the basic syntax :

conParent$aggregate('[
    { "$lookup":
        { "from":"Children", 
          "localField": "_id",
          "foreignField": "parent_id",
          "as": "children"
        }
    }
 ]')

$lookup seems to take only field name, I've tried this, producing syntaxic errors :

           .../...
           "foreignField": "{'$oid':'parent_id'}"
           .../...

So is there a way to deal with that ?

In the other way, I tried to save the parent's ObjectId in the children in ObjectId format with no luck (I still get a string in MongoDB) :

   result <- transform(
                computeFunction, 
                parent_id = sprintf('{"$oid":"%s"}',parent$"_id"))
   resultCon <- conout$insert(as.data.frame(result))

Is it possible to store an Id as ObjectId in mongolite?

Note : I'm doing bulk inserts so I can't deal with JSON string manipulations.

Any idea ?

Edit:

Here is an example of the collections i am using :

The Parent collection :

{
    "_id" : ObjectId("586f7e8b837abeabb778d2fd"),
    "name" : "Root1",
    "date" : "2017-01-01",
    "value" : 1.0,
    "value1" : 10.0,
    "value2" : 100.0
},
{
    "_id" : ObjectId("586f7ea4837abeabb778d30a"),
    "name" : "Root1",
    "date" : "2017-01-02",
    "value" : 2.0,
    "value1" : 20.0,
    "value2" : 200.0
}

The Children collection :

{
    "_id" : ObjectId("586f7edf837abeabb778d319"),
    "name" : "Item1",
    "value" : 1.1,
    "date" : "2017-01-01",
    "parent_id" : "586f7e8b837abeabb778d2fd"
}
{
    "_id" : ObjectId("586f7efa837abeabb778d324"),
    "name" : "Item2",
    "value1" : 11.111111111,
    "value2" : 12.222222222,
    "date" : "2017-01-01",
    "parent_id" : "586f7e8b837abeabb778d2fd"
}
{
    "_id" : ObjectId("586f7f15837abeabb778d328"),
    "name" : "Item1",
    "value" : 2.2,
    "date" : "2017-01-02",
    "parent_id" : "586f7ea4837abeabb778d30a"
}
{
    "_id" : ObjectId("586f7f2b837abeabb778d32e"),
    "name" : "Item2",
    "value1" : 21.111111111,
    "value2" : 22.222222222,
    "date" : "2017-01-02",
    "parent_id" : "586f7ea4837abeabb778d30a"
}
jeanjerome
  • 98
  • 8

2 Answers2

0

Could you try :

"foreignField": "_id" 

Starting from mongo's website example :

library(mongolite)
library(jsonlite)

a = '[{ "_id" : 1, "item" : 1, "price" : 12, "quantity" : 2 },
{ "_id" : 2, "item" : 2, "price" : 20, "quantity" : 1 },
{ "_id" : 3  }]'

b= '[{ "_id" : 1, "sku" : "abc", "description": "product 1", "instock" : 120 },
{ "_id" : 2, "sku" : "def", "description": "product 2", "instock" : 80 },
{ "_id" : 3, "sku" : "ijk", "description": "product 3", "instock" : 60 },
{ "_id" : 4, "sku" : "jkl", "description": "product 4", "instock" : 70 },
{ "_id" : 5, "sku": null, "description": "Incomplete" },
{ "_id" : 6 }]'

mongo_orders <- mongo(db = "mydb", collection = "orders")
mongo_orders$insert(fromJSON(a))

mongo_inventory <- mongo(db = "mydb", collection = "inventory")
mongo_inventory$insert(fromJSON(b))

df <- mongo_orders$aggregate('[
    {
      "$lookup":
        {
          "from": "inventory",
          "localField": "item",
          "foreignField": "_id",
          "as": "inventory_docs"
        }
   }
]')

str(df)

It works as well when both are set to _id

"localField": "_id",
      "foreignField": "_id",
tokiloutok
  • 467
  • 5
  • 14
  • This mongo's website example is too simple. In real life, collection's ID are differente. And in my case, the parent ID is referenced in the parent_id fields of the children. – jeanjerome Jan 06 '17 at 16:46
  • Could you give an example of your document's structure ? – tokiloutok Jan 06 '17 at 17:06
0

Well I must say that's not possible at all !

Mongilite retrieve _id as character and do not contain any ObjectId implementation.

So...

jeanjerome
  • 98
  • 8