CouchDB view with include_docs=true yields doc: null - javascript

I have 2 distinct data types in the same couchdb database, message and user. They look like follows:
// message
{
"_id": "test__032142f981b1bddd00bb9a0161688480",
"_rev": "8-d1b19caabac334c4b9e9eb1f0b0b8986",
"created": "2011-12-27T23:48:17.940699Z",
"text": "Omnis quam nesciunt dolor quaerat.",
"author_id": "test__d3f62f343144dfef8fd112946da9c1b3",
"type": "message",
"subject": "Some text"
"recipients": [
"user id 1",
"user id 2",
]
}
//user
{
"_id": "test__d3f62f343144dfef8fd112946da9c1b3",
"_rev": "12-88206492cc5274248aa5a64ff6a49b9a",
"type": "user",
"profile": {
"callname": "User name",
"fullname": "User name",
"profile_text": "Blah blah",
"urls": [
{
"url": "http://www.example.org",
"description": "CV, Blog, Pictures, Research, Links",
"label": "Homepage"
}
],
"profile_image_url": "http://localhost:5000/static/img/profiles/2e38f9fdd9e458eb4db0e7bb3b8e9576.jpg"
},
"registration_date": "2014-08-14T20:07:28Z",
"verified": "none",
"preferences": {
"lang": "en"
},
"last_login": "2014-08-14T20:07:28Z",
"email": "user#example.org"
}
Out of reasons, inlining is not a possibility in this case. What I want now is to get a list of all messages with the author object included (Like SQL SELECT * FROM messages JOIN users on message.author_id = message.id).
I read this two articles:
http://www.cmlenz.net/archives/2007/10/couchdb-joins
http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Linked_documents
So I wanted to use include_docs=true and then a list to format it nicely. My messages map function:
function(doc) {
if (doc.type == 'message') {
emit(doc._id, {_id: doc.author_id, entity: doc});
}
}
I call this using the URL http://localhost:5984/dedri/_design/dedri/_view/messages?include_docs=true. But I get this, with doc: null:
{
"total_rows": 34,
"offset": 0,
"rows": [
{
"id": "test__032142f981b1bddd00bb9a0161688480",
"key": "test__032142f981b1bddd00bb9a0161688480",
"value": {
"_id": "test__d3f62f343144dfef8fd112946da9c1b3",
"entity": {
"_id": "test__032142f981b1bddd00bb9a0161688480",
"_rev": "8-d1b19caabac334c4b9e9eb1f0b0b8986",
"created": "2011-12-27T23:48:17.940699Z",
"text": "Omnis quam nesciunt dolor quaerat.",
"version": "0.1",
"author_id": "test__d3f62f343144dfef8fd112946da9c1b3",
"type": "message",
"subject": "Some text"
}
},
"doc": null
},
...
I don't know what to do anymore. There is no editing or deleting done in the map function. Is this a problem of mine or a bug?

Try change your map js to a simpler form for debugging, e.g.
function(doc) {
if (doc.type == 'message') {
// emit(doc._id, {_id: doc.author_id, entity: doc});
emit(doc._id, { '_id': doc.author_id });
}
}

Related

How to remove deeply nested object (Node.js, mongoose)

I'm making a kanban task management app and I'm trying to remove a task with the _id: req.params.id which has the value of 62fa5ae05778ec97bc6ee23a. I tried the following:
const task = await Board.findOneAndUpdate(
{
"columns.tasks._id": req.params.id,
},
{ $pull: { "columns.$.tasks.$._id": req.params.id } },
{ new: true }
);
But I get the error Too many positional (i.e. '$') elements found in path'columns.$.tasks.$._id'
I searched for a while and came across arrayFilters from the docs but I'm struggling a lot to understand how to implement it for this particular need.
{
"_id": "62fa5aa25778ec97bc6ee231",
"user": "62f0eb5ebebd0f236abcaf9d",
"name": "Marketing Plan",
"columns": [
{
"name": "todo",
"_id": "62fa5aa25778ec97bc6ee233",
"tasks": [
{
"title": "Task Four",
"description": "This is task four",
"subtasks": [
{
"name": "wash dshes",
"completed": false,
"_id": "62fa5ae05778ec97bc6ee23b"
},
{
"name": "do homework",
"completed": false,
"_id": "62fa5ae05778ec97bc6ee23c"
}
],
"_id": "62fa5ae05778ec97bc6ee23a"
}
]
},
{
"name": "doing",
"_id": "62fa5aa25778ec97bc6ee234",
"tasks": []
},
{
"name": "done",
"_id": "62fa5aa25778ec97bc6ee235",
"tasks": []
}
],
"__v": 0
}
You need to use $[] positional operator in order to pull from the nested array. Try running this query:
db.Board.updateOne({
"_id" : "62fa5aa25778ec97bc6ee231",
}, {
$pull: { 'columns.$[].tasks': { '_id': '62fa5ae05778ec97bc6ee23a' } }
});

elasticsearch.js bulk insert error

I am trying to insert/update data with the javascript elasticsearch client, but I am getting the error:
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Malformed action/metadata line [1], expected a simple value for field [_data] but found [START_OBJECT]"
}
],
"type": "illegal_argument_exception",
"reason": "Malformed action/metadata line [1], expected a simple value for field [_data] but found [START_OBJECT]"
},
"status": 400
}
This is the data that is being sent
esclient.bulk({
body: [
{
"index":
{
"_index":"myindex",
"_type":"movie",
"_id":"1IEAEHNOIORANIT4SEOASNIE3HAETN2E...",
"_data":
{
"title":"Title 2",
"description":"This should be updated with this new data.",
"score":1,
"suggest_title":"Title 2",
"img":"http://url.to.image/img.jpeg",
"genres":["Comedy"],
"release":"2015-01-07T23:00:00.000Z",
"language":"EN",
"provider":
{
"id":"InstaFilmFlixify",
"url":"http://www.InstaFilmFlixify.com/play?id=238412"
}
}
}
}
]
})
It appears as this code generates the following request to ES:
-> POST http://docker.me:9200/_bulk
{
"index": {
"_index": "myindex",
"_type": "movie",
"_id": "1IEAEHNOIORANIT4SEOASNIE3HAETN2E...",
"_data": {
"title": "Title 2",
"description": "This should be updated with this new.",
"score": 1,
"suggest_title": "Title 2",
"img": "http://url.to.image/img.jpeg",
"genres": [
"Comedy"
],
"release": "2015-01-07T23:00:00.000Z",
"language": "EN",
"provider": {
"id": "InstaFilmFlixify",
"url": "http://www.InstaFilmFlixify.com/play?id=238412"
}
}
}
}
What am I doing wrong? What is happening? Can this possibly be a bug in ES / the ES adapter.
Elasticsearch version 2.1
I haven't seen the "_data" parameter before. Where did you get the idea to use that?
Take a look at the docs for the js client.
Anyway, this should work for you:
esclient.bulk({
body: [
{
"index":
{
"_index":"myindex",
"_type":"movie",
"_id":"1IEAEHNOIORANIT4SEOASNIE3HAETN2E...",
}
},
{
"title":"Title 2",
"description":"This should be updated with this new data.",
"score":1,
"suggest_title":"Title 2",
"img":"http://url.to.image/img.jpeg",
"genres":["Comedy"],
"release":"2015-01-07T23:00:00.000Z",
"language":"EN",
"provider":
{
"id":"InstaFilmFlixify",
"url":"http://www.InstaFilmFlixify.com/play?id=238412"
}
}
]
})

Converting Multidimensional JSON key-value pairs into an Angular Menu (no Angular knowledge required)

I asked this question here:
Working With Dynamic Multidimensional key-value pairs in JSON
But it's become a bit more involved and I can't get where I'm going from that answer. If I have a data object that looks like this:
{
"email": "user#someco.com",
"firstname": "Bob",
"lastname": "Smith",
"company": "ACME",
"custom": {
"services": [
{
"name": "svc1",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc2",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc3",
"desc": "abcdefg",
"selected": "false",
"status": "None"
},
{
"name": "svc4",
"desc": "abcdefg",
"selected": "false",
"status": "None"
}
],
"fields": [
{
"name": "Products",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Product1",
"desc": "abcdef"
},
{
"name": "Product2",
"desc": "abcdef"
}
],
"services": [
"svc1",
"svc2",
"svc3"
]
},
{
"name": "Wines",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Wine 1",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
},
{
"name": "Fruits",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Fruit 1",
"desc": "abcdef"
},
{
"name": "Fruit 2",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
}
]
}
};
How can I convert that into an Angular menu? The menu would need to list all of the services, and then if the service has an associated item in "fields" that item should be listed underneath it. So for instance "svc1" and its description should be listed on a line (got that working) but then "Product1" and "Product2" with their descriptions should appear on the next two lines because you can see that "svc1" is listed in the "services" field for "Products." Similarly, "svc4" should appear on a line, and then "Wines" and its description on the next line because "svc4" appears in the "services" field of "Wines."
I think the best way is to unpack and re-pack this JSON object in sequential order in the Angular controller and then push this data out to the Angular view but there might be a solution using only the logic available from the view. I've tried a bunch of nested fors and ifs along these lines (very much not working):
var i, j;
var listArray = [];
for (i = 0; i < $scope.svcs.length; i++) {
var littleArray = [$scope.svcs[i].status, $scope.svcs[i].name, $scope.svcs.desc];
listArray.push[littleArray1];
for (j=0; j < $scope.jFA.length; j++) {
if ($scope.jFA[j] == $scope.svcs[i].name) {
if ($scope.jFA[j] == $scope.svcs[i].fields)
littleArray = [$scope.jFA[j].fields] //...etc
}
}
...but that logic just keeps getting more and more dense and isn't working no matter now I try to use it. I liked the simplicity in the answer to the other question but have not had success in replicating it.
So if someone can help me figure out how to get the data into the right sequence using JS I can handle the Angular part. Or if you're an Angular whiz and have an answer along those lines, even better.
So it was a little hard understanding your question, but I gave it my best shot. Does this fiddle show what you are trying to achieve? http://jsfiddle.net/arknr6qz/1/
JS:
var app = angular.module('TestApp',[]);
app.controller('TestController', function($scope)
{
$scope.checkService = function(service, fieldServices)
{
if (fieldServices.indexOf(service) != -1) return true;
return false;
};
$scope.data = {
"email": "user#someco.com",
"firstname": "Bob",
"lastname": "Smith",
"company": "ACME",
"custom": {
"services": [
{
"name": "svc1",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc2",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc3",
"desc": "abcdefg",
"selected": "false",
"status": "None"
},
{
"name": "svc4",
"desc": "abcdefg",
"selected": "false",
"status": "None"
}
],
"fields": [
{
"name": "Products",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Product1",
"desc": "abcdef"
},
{
"name": "Product2",
"desc": "abcdef"
}
],
"services": [
"svc1",
"svc2",
"svc3"
]
},
{
"name": "Wines",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Wine 1",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
},
{
"name": "Fruits",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Fruit 1",
"desc": "abcdef"
},
{
"name": "Fruit 2",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
}
]
}
};
});
HTML:
<div ng-app="TestApp">
<div ng-controller="TestController">
<div ng-repeat="service in data.custom.services">
{{ service.name }}
<div class="indent" ng-repeat="fields in data.custom.fields">
<span ng-if="checkService(service.name, fields.services)">
{{fields.services.values}}
<span ng-repeat="value in fields.values">
{{value.name}} - {{value.desc}}<br>
</span>
</span>
</div>
</div>
</div>
</div>
and finally css:
.indent {
margin-left:10px;
}

Passing function argument to retrieve data from an object

I am have some trouble with a script I am working on. I have been provided with an object with multiple items from a product catalog.
What I am trying to do is to write a function which to which will allow me to render this data easily.
<script type="application/javascript">
SKUinfo =
{
"s238554": {
"Age": {
"Description": "Age 18+",
"Thumbnail": "/productImages/assets/img/icon18.gif"
},
"Barcode": {
"Barcode": "50622132430794"
},
"Currency": "£",
"Description": "Description goes here",
"Id": 44305,
"Packshots": [
"/productImages/238556/1min.jpg",
"/productImages/238556/2med.jpg",
"/productImages/238556/3max.jpg"
],
"Pegis": [],
"Platform": {
"Button": "Xbox 360",
"ID": 0
},
"Publisher": {
"Description": null
},
"Release": "/Date(1392940800000+0000)/",
"Screenshots": [
{
"ScreenshotMax": "/productImages/238556/5scrmax1.jpg",
"ScreenshotMin": "/productImages/238556/4scrmin1.jpg"
}
],
"Title": "Product title 2 goes here",
"Variants": [
{
"Id": 58242,
"MaxOrderQuantity": 3,
"Presellable": true,
"Price": 29.97,
"PriceCultureFormat": "29.97",
"PriceWithCurrencyFormat": "£29.97",
"Sku": 238556,
"Type": {
"Description": "New"
}
},
],
"Vendor": {
"Description": ""
},
},
"s238556": {
"Age": {
"Description": "Age 18+",
"Thumbnail": "/productImages/assets/img/pegi/icon18.gif"
},
"Barcode": {
"Barcode": "5060134530794"
},
"Currency": "£",
"Description": "Description here",
"Id": 654654,
"Packshots": [
"/productImages/238556/1min.jpg",
"/productImages/238556/2med.jpg",
"/productImages/238556/3max.jpg"
],
"Pegis": [],
"Platform": {
"Button": "PlayStation 3",
"ID": 0
},
"Publisher": {
"Description": null
},
"Release": "/Date(1392940800000+0000)/",
"Screenshots": [
{
"ScreenshotMax": "/productImages/238556/5scrmax1.jpg",
"ScreenshotMin": "/productImages/238556/4scrmin1.jpg"
},
{
"ScreenshotMax": "/productImages/238556/7scrmax2.jpg",
"ScreenshotMin": "/productImages/238556/6scrmin2.jpg"
},
],
"Title": "Product title 2 goes here",
"Variants": [
{
"Id": 58242,
"MaxOrderQuantity": 3,
"Presellable": true,
"Price": 29.97,
"PriceCultureFormat": "29.97",
"PriceWithCurrencyFormat": "£29.97",
"Sku": 238556,
"Type": {
"Description": "New"
}
},
],
"Vendor": {
"Description": ""
},
"VideoHTML": "html here",
"status": {
"Response": "product found",
"Success": true
}
}
}
</script>
The above example is the output I get for two products.
If I try to get access to this data this is where I have a problem
<script type="application/javascript">
function getSKU(s)
{
console.log(SKUinfo.s.Title);
}
getSKU(s238554);
</script>
I imagine this is being caused when I am passing the argument s back to the function getSKU a the node selection in the data object. In this I would expect the console output to be the Title from SKU s238554.
What I get however, is: Uncaught ReferenceError: s238554 is not defined
I would appreciate any guidance that can be offered as I am a javascript novice.
Access your property by used[] on SKUinfo.s.Title like SKUinfo[s].Title
And also pass your property name within the quotes 's238554' as it's not variable.
Something like this.
function getSKU(s){
console.log(SKUinfo[s].Title);
}
getSKU('s238554'); // s238554 within quotes.

Getting Messages from Inbox

I have a question about the Graph API.
I use Javascript for the API and make a little test website ,where you can log in ,look for new messages and write a new status.
My problem is that I can't get the messages or the thread.
FB.api('/me/inbox',function(response) { alert(response.id); } ); don't work.
Have somebody an example for getting the messages in the inbox??
Thanks
The /me/inbox request requires that you have the read_mailbox permission granted.
Once you've got that, the /me/inbox request will return an array of Thread's, which will look something like this;
{
"data": [
{
"id": "1126884978255",
"from": {
"name": "Someone's Name",
"id": "34723472"
},
"to": {
"data": [
{
"name": "Someone's Name",
"id": "34723472"
},
{
"name": "Matt Lunn",
"id": "560914724"
}
]
},
"message": "Testing the one-ness.",
"updated_time": "2012-01-31T12:13:00+0000",
"unread": 0,
"unseen": 0,
"comments": {
"data": [
{
"id": "1126884978255_6769",
"from": {
"name": "Someone's Name",
"id": "34723472"
},
"message": "£140!?",
"created_time": "2012-01-31T11:33:15+0000"
},
{
"id": "1126884978255_6771",
"from": {
"name": "Matt Lunn",
"id": "560914724"
},
"message": "^^ month in advance as well",
"created_time": "2012-01-31T11:33:26+0000"
}
]
},
"type": "thread"
}
],
"summary": {
"unseen_count": 0,
"unread_count": 21,
"updated_time": "2012-01-31T13:19:31+0000"
}
}
So depending which ID you're after, you'll have to do;
for (var i=0;i<response.data.length;i++) {
var thread = response.data[i];
for (var j=0;j<thread.comments.data.length;j++) {
var comment = thread.comments.data[j];
console.log(comment.message);
}
}
Hopefully you get the idea...

Categories

Resources