Why MongoDB saves Hash value in different format? - mongodb

I am learning IPFS and trying to save IPFS file info in MongoDB. After uploading, I get one hash value
ex: {fileHash: CID(QmbCaWPi9tSqcnykvBUMaH2M1d5PiVPLEfPwhJksSSeMak)}
And in MongoDB, I see something like this:
"fileHash": {
"code": 112,
"version": 0,
"multihash": {
"code": 18,
"size": 32,
"digest": "vxaISoMOXTpFy9rwnYilyk7pa6TlhkFDCZgcjGhXfm0=",
"bytes": "EiC/FohKgw5dOkXL2vCdiKXKTulrpOWGQUMJmByMaFd+bQ=="
},
"bytes": "EiC/FohKgw5dOkXL2vCdiKXKTulrpOWGQUMJmByMaFd+bQ=="
}
Now I want to update this document based on hash value but don't understand what value I compare in match.
db.collection("test").update(filter, set);
I was trying like this:
db.collection("test").update({fileHash:"CID(QmbCaWPi9tSqcnykvBUMaH2M1d5PiVPLEfPwhJksSSeMak)"}, set);
But it doesn't work

I think CID() is like a function.
When you use CID("QmbCaWPi9tSqcnykvBUMaH2M1d5PiVPLEfPwhJksSSeMak"), it come up with a JSON.
{
"code": 112,
"version": 0,
"multihash": {
"code": 18,
"size": 32,
"digest": "vxaISoMOXTpFy9rwnYilyk7pa6TlhkFDCZgcjGhXfm0=",
"bytes": "EiC/FohKgw5dOkXL2vCdiKXKTulrpOWGQUMJmByMaFd+bQ=="
},
"bytes": "EiC/FohKgw5dOkXL2vCdiKXKTulrpOWGQUMJmByMaFd+bQ=="
}
So you should try something like
let fileHash = CID("QmbCaWPi9tSqcnykvBUMaH2M1d5PiVPLEfPwhJksSSeMak");
db.collection("test").update({fileHash: fileHash }, set);

Take that CID and use the method toString() on it.

Related

Paggination on api data in flutter

i get data from API like demo:-
{draw: 0, records Total: 210, records Filtered: 210, data: [,…], input: []}
data: [,…]
draw: 0
input: []
records Filtered: 210
records Total: 210
I want to apply paggination on API data (grid view or list view)
How can i do that ?
Your json structure needs to look like this to apply pagination with ease.
Use current page, next page and last page to determine the next, current and remaining pages.
You can directly use the next link to get the data of the next page.
{
"meta": {
"page": {
"current-page": 2,
"per-page": 15,
"from": 16,
"to": 30,
"total": 50,
"last-page": 4
}
},
"links": {
"first": "http://localhost/api/v1/posts?page[number]=1&page[size]=15",
"prev": "http://localhost/api/v1/posts?page[number]=1&page[size]=15",
"next": "http://localhost/api/v1/posts?page[number]=3&page[size]=15",
"last": "http://localhost/api/v1/posts?page[number]=4&page[size]=15"
},
"data": [...]
}

Update and append decoded JSON into struct?

I'm receiving some paginated JSON response through my API that looks something like this:
page 1:
{
"count": 96,
"next": "http://127.0.0.1:8000/id=5/?page=2",
"previous": null,
"results": [
{
"id": 10,
"book_name": "Book name",
"book_id": 70,
"chapter_number": 1,
"verse": "Verse title here",
"verse_number": 1,
"chapter": 96
},
{
"id": 198,
"book_name": "Book Name",
"book_id": 70,
"chapter_number": 8,
"verse": "Text here",
"verse_number": 5,
"chapter": 103
}
]
}
As I move through the paginated result, ie calling: http://127.0.0.1:8000/id=5/?page=2
I'll get new values in the results array.
page 2:
{
"count": 96,
"next": "http://127.0.0.1:8000/id=5/?page=3",
"previous": "http://127.0.0.1:8000/id=5/",
"results": [
{
"id": 206,
"book_name": "Book on Second page",
"book_id": 70,
"chapter_number": 8,
"verse": "yadda yadda",
"verse_number": 13,
"chapter": 103
},
{
"id": 382,
"book_name": "Book on second page..",
"book_id": 70,
"chapter_number": 15,
"verse": "Verse here",
"verse_number": 12,
"chapter": 110
}
]
}
How would I structure my struct/fix my decoding so I can append the values of results from the JSON while still updating count, next and previous as I go through ..?page=3, ..?page=4 etc
Currently, my struct looks like this:
struct VersesSearchResult: Decodable {
var results: [Verse]
var count: Int
var next: String?
var previous: String?
}
When doing the decoding, I'm not sure what the syntax should be like to append results to the struct, and update next, previous, and count. So far I got this
...
let verses = try JSONDecoder().decode(VersesSearchResult, from: safeData)
DispatchQueue.main.async {
// somehow need to get this to work - not entirely sure how
// where results gets appended, while the rest in the JSON values gets updated
// obviously I can't do as below:
self.verseSearchResult.append(contentsOf: verses.results)
self.verseSearchResult = verses
}
...
Decode to a temprary instance of the type, then process those properties into your main instance. Depending how you want to process the data, it'll look something like this
extension VersesSearchResult {
mutating func update(with new: VersesSearchResult) {
results.append(new)
count = new.count
next = new.next
prev = new.prev
}
}
and then in your completion block
let newVerses = try JSONDecoder().decode(VersesSearchResult, from: safeData)
self.verses.update(with: newVerses)
If needs be force the update onto the main thread.
You should also handle failure in the 'try' either with a do...catch or other approach.

Azure OCR difference between demo page and console

I have several examples of images I need to recognize with OCR.
I've tried to recognize them on the demo page https://azure.microsoft.com/en-us/services/cognitive-services/computer-vision/ and it works quite well. I use the "Read text in images" option, which works even better than "Read handwritten text from images".
But when I try to use the REST call from a script (according to the example given in documentation) results are much worse. Some letters are recognized wrong, some are totally missed. If I try running the same example from the development console https://westcentralus.dev.cognitive.microsoft.com/docs/services/5adf991815e1060e6355ad44/operations/56f91f2e778daf14a499e1fc/console I still get the same bad results.
What can cause this difference? How can I fix it to get reliable results as the demo page produces?
Maybe any additional information is required?
UPD: since I couldn't find any solution or even explanation of the difference I've created a sample file (similar to actual files) so you can have a look. The file url is http://sfiles.herokuapp.com/sample.png
You can see, if it is used on the demo page https://azure.microsoft.com/en-us/services/cognitive-services/computer-vision/ in section "Read text in images" the resulting JSON is
{
"status": "Succeeded",
"succeeded": true,
"failed": false,
"finished": true,
"recognitionResult": {
"lines": [
{
"boundingBox": [
307,
159,
385,
158,
386,
173,
308,
174
],
"text": "October 2011",
"words": [
{
"boundingBox": [
308,
160,
357,
160,
357,
174,
308,
175
],
"text": "October"
},
{
"boundingBox": [
357,
160,
387,
159,
387,
174,
357,
174
],
"text": "2011"
}
]
},
{
"boundingBox": [
426,
157,
519,
158,
519,
173,
425,
172
],
"text": "07UC14PII0244",
"words": [
{
"boundingBox": [
426,
160,
520,
159,
520,
174,
426,
174
],
"text": "07UC14PII0244"
}
]
}
]
}
}
If I use this file in the console and make the following call:
POST https://westcentralus.api.cognitive.microsoft.com/vision/v2.0/ocr?language=unk&detectOrientation =true HTTP/1.1
Host: westcentralus.api.cognitive.microsoft.com
Content-Type: application/json
Ocp-Apim-Subscription-Key: ••••••••••••••••••••••••••••••••
{"url":"http://sfiles.herokuapp.com/sample.png"}
I get different result:
{
"language": "el",
"textAngle": 0.0,
"orientation": "Up",
"regions": [{
"boundingBox": "309,161,75,10",
"lines": [{
"boundingBox": "309,161,75,10",
"words": [{
"boundingBox": "309,161,46,10",
"text": "October"
}, {
"boundingBox": "358,162,26,9",
"text": "2011"
}]
}]
}, {
"boundingBox": "428,161,92,10",
"lines": [{
"boundingBox": "428,161,92,10",
"words": [{
"boundingBox": "428,161,92,10",
"text": "071_lC14P110244"
}]
}]
}]
}
As you see the result is totally different (even the JSON format). Does anyone know what am I doing wrong, or maybe I'm missing something, and the "Read text in images" demo does not match the ocr method of the API?
Will be very grateful for any help.
There are two flavors of OCR in Microsoft Cognitive Services. The newer endpoint (/recognizeText) has better recognition capabilities, but currently only supports English. The older endpoint (/ocr) has broader language coverage.
Some additional details about the differences are in this post.

Split json using NiFi

I have a json with all the records with merged I need to split the merged json and load in separate database using NiFi
My file when I execute
db.collection.findOne()
My input looks like:
[
{
"name": "sai",
"id": 101,
"company": "adsdr"
},
{
"name": "siva",
"id": 102,
"company": "shar"
},
{
"name": "vanai",
"id": 103,
"company": "ddr"
},
{
"name": "karti",
"id": 104,
"company": "sir"
}
]
I am getting all the json. I need to get output as:
{name: "sai", id:101, company: "sdr"}
So i only want one record, how can I parse the json using NiFi?
There is a SplitJson processor for this purpose:
https://nifi.apache.org/docs/nifi-docs/components/org.apache.nifi.processors.standard.SplitJson/index.html
There are various JSON Path testers online to come up with the correct expression:
https://jsonpath.curiousconcept.com/
Use Split json processor with below configs as shown in the below screenshot
SplitJson Config
As Bryan said, you can use SplitJson processor, and then, you can forward the splitted data flow to other databases. The processor internally using this json pathfinder. You can read there the operations that the processor supports.
Just use this to get the first element by:
// JSON Path Expression for the first element:
$[0]
[
{
"name": "sai",
"id": 101,
"company": "adsdr"
}
]

What are the recommended ways to handle references to embedded documents in MongoDB?

I'm new to MongoDB. Here's my problem: a user can have multiple avatars, but one and only one is active. Here's what a user document looks like for the moment:
{
"_id": ObjectId("515c99f7e4d8094a87e13757"),
"avatars": [{
"url": "http://example.com/img/photo1.jpg",
"width": 50,
"height": 50,
}, {
"active": true,
"url": "http://example.com/img/photo2.jpg",
"width": 50,
"height": 50,
}]
}
This solution is simple enough, but there are a few things I don't like:
changing the active avatar means updating two embedded documents
I'm not sure it will behave nicely in case of concurrent access (read_avatar+change_active_avatar or change_active+change_active) (will it?)
looking for the active avatar requires a sequential search
Another solution would be this:
{
"_id": ObjectId("515c99f7e4d8094a87e13757"),
"active_avatar_id": 2,
"avatars": [{
"_id": 1,
"url": "http://example.com/img/photo1.jpg",
"width": 50,
"height": 50,
}, {
"_id": 2,
"url": "http://example.com/img/photo2.jpg",
"width": 50,
"height": 50,
}]
}
This fixes problems 1&2, but not problem 3. And it adds an extra _id field in every embedded document. Plus when I insert a new avatar I now need to know what's the next _id to use (unless I use an objectId, but then it's a 12 bytes id for just a few hundred avatars (max).
So yet another solution could be this:
{
"_id": ObjectId("515c99f7e4d8094a87e13757"),
"active_avatar": {
"url": "http://example.com/img/photo2.jpg",
"width": 50,
"height": 50,
},
"extra_avatars": [{
"url": "http://example.com/img/photo1.jpg",
"width": 50,
"height": 50,
}]
}
Not much better than the first solution (it just fixes problem #3, that's it, and it's uglier).
All these solutions work, but I'm looking for "the right way" to do it. Any ideas? And what if I allow users to have multiple active avatars (whatever that would mean)?
Thanks.
Have you considered the document inside a document model?
{
"_id" : ObjectId("515c99f7e4d8094a87e13758"),
"active_avatar_id" : 2,
"avatars" : {
"1" : {
"url" : "http://example.com/img/photo1.jpg",
"width" : 50,
"height" : 50
},
"2" : {
"url" : "http://example.com/img/photo2.jpg",
"width" : 50,
"height" : 50
}
}
}