CosmoDb with Robomongo cant see document id's? - mongodb

Can anyone tell me why when I use DataExplorer for CosmoDb DB I get the following:
{
"id": "d502b51a-e70a-40f1-9285-3861880b8d90",
"Version": 1,
...
}
But when I use Robomongo I get:
{
"Version" : 1,
...
}
minus the id?
Thanks

I tried to repro your scenario but it all worked correctly.
The Mongo document in Portal Data Explorer:
The Mongo document in Robo 3T:
They both have the id property.
Are you applying Projections on Robomongo / Robo 3T?

At this moment cosmodb works separately SQL API and Mongo API, each one has different implementation, SQL API use JSON and Mongo use BSON, you need to be clear this while you are creating the document.
If you create the document with a BSON-based tool like Robo3t for example, you are going to get something like this:
{
"_id": {
"$oid": "5be0d98b9cdcce3c6ce0f6b8"
},
"name": "Name",
"id": "5be0d98b9cdcce3c6ce0f6b8",
...
}
Instead, if you create your document with JSON-based like Data Explorer, you are going to get this:
{
"name": "Name",
"id": "6c5c05b4-dfce-32a5-0779-e30821e6c510",
...
}
As you can see, BSON-based needs that _id and inside $oid be implemented to works right, while JSON-based only id is required. So, you need to add the properties while you save the document (see below) or open it with the right tool, as Matias Quaranta recommend, use Azure Storage Explorer or even Data Explorer to get both protocols properly.
Also, if you use a system to create the document and you want to use BSON format, You need to add the $oid, for example in core net is something like this:
public bool TryGetMemberSerializationInfo(string memberName, out BsonSerializationInfo serializationInfo)
{
switch (memberName)
{
case "Id":
serializationInfo = new BsonSerializationInfo("_id", new ObjectIdSerializer(), typeof(ObjectId));
return true;
case "Name":
serializationInfo = new BsonSerializationInfo("name", new StringSerializer(), typeof(string));
return true;
default:
serializationInfo = null;
return false;
}
}

Related

Why can't I insert my data into my MongoDB database?

I have exported one of my collections from MongoDB and it looks like the following:
[
{
"_class": "test.Tag",
"title": "My Title",
"_id": {
"$oid": "637a2bc4a9c297b306dd0be9"
}
}
]
Now, I want to add another item to this collection.
I have created a json file exactly in the same format.
However, when I use the following command:
db.tag.insertMany([{"_class": "test.Tag", "title": "New Title","_id": {"$oid": "637a4171833047f9e046f3c9"}}])
I get the error:
MongoBulkWriteError: _id fields may not contain '$'-prefixed fields: $oid is not valid for storage.
I found a couple of similar questions on stackoverflow, e.g. this one, but they didn't help me.
How should I insert something in my database?
When I use MongoDB Compass, there is no problem. It works. But when I try it on my real database on the server, it doesn't work.
If it helps, I am using Mongo version 6.0.1.
Your help would be appreciated.
In the legacy mongo shell there is no helper for extended json format , but in mongosh you can use EJSON to deserialize the extended json and insert it as follow:
> db.test4.insertMany([EJSON.deserialize( {"_id": { "$oid": "637aa8243d58f36141e59c8d"} } )])
{
acknowledged: true,
insertedIds: { '0': new ObjectId("637aa8243d58f36141e59c8d") }
}
>
( The legacy mongo shell was deprecated in MongoDB 5.0 and removed in MongoDB 6.0 )

How do I auto insert a timestamp, into my document when a document is created / edited?

I'm just getting started with mongoDB, and coming from a MySQL environment I'm having trouble figuring out how have my documents automatically have fields such as UPDATED, CREATED, DELETED
So when I create an entry like this:
{
"email": "some#test.com",
"name": "bob"
}
I would like it to automatically become this:
{
"email": "some#test.com",
"name": "bob",
"CREATED": 1567120458,
"UPDATED": 1567120458,
"DELETED": null
}
I have found https://docs.mongodb.com/manual/reference/operator/update/currentDate/ this resource which talks about a way of inserting dates, but I am not sure how to use this, or where to place this.
{ $currentDate: { <field1>: <typeSpecification1>, ... } }
I don't know what this piece of code means or where to use it.
I've installed Stuido 3T to help me manage the database, but I don't see any option to use this piece of code.
Construct your query use Date:
db.example.insert({"date":new Date(Date.now())})

Find DocumentId through Discovery GUI tool

I want to train my Discovery collection where I have already uploaded over 200 documents. I uploaded these documents through the GUI. Looking through the Discovery documentation, I know that I have will have to make API calls to train my collection since the training API has not been exposed through the GUI yet. As part of the training API calls I need to include a document that looks like this:
{
"natural_language_query": "{natural_language_query}",
"filter": "{filter_definition}"
"examples": [
{
"document_id": "{document_id_1}",
"cross_reference": "{cross_reference_1}",
"relevance": 0
},
{
"document_id": "{document_id_2}",
"cross_reference": "{cross_reference_2}",
"relevance": 0
}
]
}
My question is how should I get the documentIds for the documents that I have already uploaded? Is there a way to find this through the GUI? Or perhaps an API call that will return something like:
{
"document_name" = "MyDocument1",
"documentId" = "the_document_id_for_MyDocument1"
},
...
{
"document_name" = "MyDocumentN",
"documentId" = "the_document_id_for_MyDocumentN"
}
Or would the only way to get the documentIds would be to create a new collection and upload all of the documents through API calls directly and track the documentIds as I get them back?
Using the GUI, perform the following steps:
Input term(_id) in the "Group query results (Aggregation)"
textbox.
Under "Fields to return", select "Specify" to input
extracted_metadata
Note, that query and filter inputs should remain empty

How to query Cloudant documents for a specific field

I am new to Cloudant and I need to do a simple query on a specific document field. My documents have the following structure and I need to get only the documents with status=SIGNED
{
"_id": "3ddb4058f3b24a7a9c585f997e30ff78",
"_rev": "3-757c82c48f4e7c333911be6859aff74e",
"fileName": "Generali Architects",
"status": "SIGNED",
"user": "italy",
"_attachments": {
"Generali Architects": {
"content_type": "application/pdf",
"revpos": 3,
"digest": "md5-9hqSif7CzQ2yvKxSSbj+dw==",
"length": 323653,
"stub": true
}
}
}
Reading Cloudant documentation I created the following Design Document with a related view which returns exactly what I expected
Then from my Java application I use the following code
String cloudantView = "_design/signedDocs/status-signed-iew";
List<SignDocDocument> docs =
db.view(cloudantView).includeDocs(true).query(SignDocDocument.class);
which always returns me "org.lightcouch.NoDocumentException: Object Not Found"
Any idea which kind of mistake I am making here?
Thank you very much
Is it the typo in "_design/signedDocs/status-signed-iew"; e.g. that should be "_design/signedDocs/status-signed-view"; (depending on how your java library works...).
Always worth checking the view by direct access in your browser, too, just to make sure it's returning the expected data.

MongoDB - Manual Referencing Without Application

I understand Manual referencing being, one document containing the reference to another.
As in the MongoDB's documentation:
original_id = ObjectId()
db.places.insert({
"_id": original_id,
"name": "Broadway Center",
"url": "bc.example.net"
})
db.people.insert({
"name": "Erin",
"places_id": original_id,
"url": "bc.example.net/Erin"
})
I am able to use a find on the places to get a certain name.
db.places.find({name : "Broadway Center"});
This will give the id. And then my application can use this ID to query the people to see who live here?
But, If i dont have a application. How would I go about doing this solely in a mongo shell? I was thinking about using find, and then iterating over the cursor using a forEach? But this seems a bit hacky.
Any suggestions?
You don't need to loop through using the cursor from find(), just use findOne() because a single document is returned with this method and you have access to the document directly (no need to apply cursor methods to the result). In mongo shell you can do this:
var result = db.places.findOne({name : "Broadway Center"});
if (result) {
var place_id = result._id;
var peopleArray = db.people.find({ "places_id": place_id }).toArray();
if (peopleArray.length > 0) { printjson (peopleArray[0]); }
}