Update node key index in batch operation - neo4j

Short
I can't get neo to update existing node properties in a batched rest op.
Long
I want to create a batch operation that inserts/updates a node inside an index. It should handle three use-cases:
if the node does not exist, insert it with the given properties set
if the node exists, update it's properties set with the new values, if any.
I'm using the batch operation api, I wrote a test where I'm issuing two requests:
Short
1. first one inserts the node and indexes it's properties
2. second one simply updates some properties of the node
Here's the first request:
[
{
"method": "POST",
"to": "/index/node/events?uniqueness=get_or_create",
"id": 1,
"body": {
"key": "id",
"value": "222222222",
"properties": {
"id": "222222222",
"type": "event-type"
}
}
},
{
"method": "POST",
"to": "/index/node/events",
"body": {
"uri": "{1}",
"key": "id",
"value": "222222222"
}
},
{
"method": "POST",
"to": "/index/node/events",
"body": {
"uri": "{1}",
"key": "type",
"value": "event-type"
}
} ]
And now the second one.
[
{
method: 'POST',
to: '/index/node/events?uniqueness=get_or_create',
id: 1,
body: {
key: 'id',
value: '222222222',
properties: {id: '222222222', type: 'event-type', title: 'SUPEREVENT'}
}
},
{
method: 'POST',
to: '/index/node/events',
body: {
uri: '{1}',
key: 'id',
value: '222222222'
}
},
{
method: 'POST',
to: '/index/node/events',
body: {
uri: '{1}',
key: 'type',
value: 'event-type'
}
},
{
method: 'POST',
to: '/index/node/events',
body: {
uri: '{
1
}',
key: 'title',
value: 'SUPEREVENT'
}
}
]
NOTE! that on the second request i'm adding and event title property with value SUPEREVENT. This does not get persisted nor indexed. Why? and how can I fix it?
Thank you,
Alex

From the doc:
URL Parameter uniqueness=get_or_create: Create a new node/relationship
and index it if no existing one can be found. If an existing
node/relationship is found, discard the sent data and return the
existing node/relationship.
So your second request's data will be discarded. You need to split each of your requests in two requests each, and do two batches. Each of the two batches has two instructions: first one creates the node if not present, and the second one updates the properties.

Related

Extjs 6.7 TreeList load data infinite from remote store

I try to fill a treelist with remote data via a ajax proxy but the treelist shows only the first level and try to reload the sub levels even though the json response contain a complete tree structure. Fiddle link: https://fiddle.sencha.com/#view/editor&fiddle/33u9
When i try to expand the node 'SUB a' (or set the expanded property to true) the store trys to reload the node.
Why is the tree structure from the json response not honored?
Thanks in Advance.
The backend response looks like:
{
"data": {
"root": [
{
"leaf": true,
"text": "Server"
},
{
"leaf": true,
"text": "Storage"
},
{
"text": "SUB a"
"children": [
{
"leaf": true,
"text": "Modul A - 1"
},
{
"leaf": true,
"text": "Modul A - 2"
}
],
},
{
"leaf": true,
"text": "Modul B"
}
]
},
"success": true
}
The used reader config is
reader: {
type: 'json',
rootProperty: 'data.root',
successProperty: 'data.success',
},
After playing around i use the following workaround:
getNavigation: function() {
var me = this,
tree = me.getView().down('navigationtree'),
store = tree.getStore(),
node = store.getRoot();
Ext.Ajax.request({
url: '/getnav',
method: 'POST',
success: function(response) {
var obj = Ext.decode(response.responseText),
childs = obj.data.root;
tree.suspendEvents();
node.removeAll();
childs.forEach(function(item) {
node.appendChild(item);
});
tree.resumeEvents();
},
failure: function(response) {
//debugger;
console.log('server-side failure with status code ' + response.status);
}
}).then(function() {
//debugger;
}
);
}
The funny things is that only the first level of the tree has to be added all following sub-levels are added automaticaly.

Webix not showing the kids data on dynamic loading

I am using webix to show some tree table data.
webix.ready(function () {
grida = webix.ui({
container: "testB",
view: "treetable",
columns: [
{ id: "id", header: "", css: { "text-align": "right" } },
{
id: "SerialNo", header: "Serial No", width: 250,
template: "{common.treetable()} #SerialNo#"
}
],
url: "/Test/GetTreeItem",
autoheight: true,
});
});
This loads the items perfectly.
Parents;
[{"id":11583,"Id":11583,"SerialNo":"12476127654","webix_kids":1},{"id":11584,"Id":11584,"SerialNo":"125235463","webix_kids":1},{"id":11585,"Id":11585,"SerialNo":"21385423348956","webix_kids":1},{"id":11586,"Id":11586,"SerialNo":"253346346346","webix_kids":1},{"id":11587,"Id":11587,"SerialNo":"123123","webix_kids":1},{"id":11588,"Id":11588,"SerialNo":"52354263","webix_kids":1},{"id":11589,"Id":11589,"SerialNo":"12344444","webix_kids":1},{"id":11590,"Id":11590,"SerialNo":"12344444","webix_kids":1},{"id":11591,"Id":11591,"SerialNo":"12344444","webix_kids":1},{"id":11592,"Id":11592,"SerialNo":"151515","webix_kids":1}]
However when I click the plus button, server returns (I can see the json string when I debug the code) the json but webix not appending the data underneath the parent.
Kids of parent "id":11587;
[{"id":11583,"Id":11583,"SerialNo":"12476127654","webix_kids":1},{"id":11592,"Id":11592,"SerialNo":"151515","webix_kids":1}]
id of data object must be unique per component.
Currently, you have for top level
{
"id": 11583,
"Id": 11583,
"SerialNo": "12476127654",
"webix_kids": 1
},
and in kids data you have
{
"id": 11583,
"Id": 11583,
"SerialNo": "12476127654",
"webix_kids": 1
},
both items share the same id, so treetable doesn't add a new item.
Correcting the JSON output solved my problem.
For the parents;
{
"parent":"0",
"data":[
{
"Id":11584,
"id":11584,
"SerialNo":"125235463",
"webix_kids":1
},
{
"Id":11599,
"id":11599,
"SerialNo":"3444",
"webix_kids":1
}
]
}
For the kids;
{
"parent":11599,
"data":[
{
"id":11583,
"Id":11583,
"SerialNo":"12476127654",
"webix_kids":1
},
{
"id":11592,
"Id":11592,
"SerialNo":"151515",
"webix_kids":1
}
]
}

How to implement appendable list of embedded objects

I'm attempting to use Eve to provide an RESTful API for a simple list of items.
I'd like to use 1) one HTTP request to create a list (possibly with initial items), 2) one HTTP request to add an item(s) (a common operation), 3) one HTTP request to get the list (including all child items). In other words:
1) POST /lists with body
{
"title": "My List",
"items": [{
"name": "Alice"
},
{
"name": "Bob"
}]
}
2) POST /lists/555555555555555555555555/items with body
{
"name": "Carol"
}
3) GET /lists/555555555555555555555555
{
"_id": "555555555555555555555555",
"title": "My List",
"items": [{
"_id": "aaaaaaaaaaaaaaaaaaaaaaaa",
"name": "Alice"
},
{
"_id": "bbbbbbbbbbbbbbbbbbbbbbbb",
"name": "Bob"
},
{
"_id": "cccccccccccccccccccccccc",
"name": "Carol"
}]
}
I haven't figured out how to do this with Eve. I can do (1) using an embedded list of dicts, but then I can't do (2)—I'd have to POST an item and then PATCH the list (?). I can do (2) using sub-resources, but then I can't do (1) ("value '{'name': 'Alice'}' cannot be converted to a ObjectId"). Or am I missing something?
If all three can't be done, could at least both (2) and (3)?
I figured out how to implement (2) and (3), using database event hooks to inject the embedded child documents into the parent list before it's returned to the client (and also delete the children when the parent is deleted). This works and supports the expected REST usage on individual list items. It results in two DB queries, however.
I suspect (1) could also be implemented using an event hook, but this will suffice for now.
Any further improvements/suggestions are welcome. It would be nice if there were an easier way to accomplish this (keywords: One-to-Many Relationships with Embedded Documents).
settings.py:
RESOURCE_METHODS = ['GET', 'POST', 'DELETE']
ITEM_METHODS = ['GET', 'PUT', 'PATCH', 'DELETE']
lists = {
'schema': {
'title': {
'type': 'string'
}
}
}
items = {
'url': 'lists/<regex("[a-f0-9]{24}"):list_id>/items',
'schema': {
'name': {'type': 'string',
'required': True
},
'list_id': {
'type': 'objectid',
'required': True,
'data_relation': {
'resource': 'lists',
'field': '_id'
}
}
}
}
DOMAIN = {
'lists': lists,
'items': items
}
main.py:
from bson.objectid import ObjectId
def before_returning_lists(response):
list_id = response['_id']
response['items'] = list(db.items.find({'list_id': ObjectId(list_id)}))
def after_deleting_lists(item):
list_id = item['_id']
db.items.delete_many({'list_id': ObjectId(list_id)})
app.on_fetched_item_lists += after_fetching_lists
app.on_deleted_item_lists += after_deleting_lists
Usage
curl -X POST http://127.0.0.1:5000/lists -d title="My List"
# (2)
curl -X POST http://127.0.0.1:5000/lists/5895fdb5a663e2dcad9e7647/items -d 'name=Alice'
curl -X POST http://127.0.0.1:5000/lists/5895fdb5a663e2dcad9e7647/items -d 'name=Bob'
curl -X POST http://127.0.0.1:5000/lists/5895fdb5a663e2dcad9e7647/items -d 'name=Carol'
# (3)
curl -X GET http://127.0.0.1:5000/lists/5895fdb5a663e2dcad9e7647

Embedded object in loopback model schema for Swagger

In the context of a remote method, I'm trying to define a model schema of a parameter passed in the body. This object looks like this:
{
name: "Alex",
credentials: {
user: "alex",
pass: "pass"
}
}
So, I have this code in my remote method definition:
MyModel.remoteMethod("postSomething", {
accepts: [
{arg: 'person', type: {
"name": "string",
"credentials": {
"type": "object",
"properties": {
"user": "string",
"pass: "string"
}
}
}, http: {source: 'body'}, required: true
}
],
.....
Unfortunatelly, the details of this embedded object (credentials) are not shown in the generated Swagger explorer. This is what I see:
{
"user": "string",
"credentials": {}
}
I've tried many different ways but I could not show the properties of the credentials object.
Any ideas?
Loopback 2.x
Edit: Note the following only works for Loopback 2.x, as the type registry changed in 3.x.
The problem is that the data you are providing needs to be on the type property for the nested value. This should work:
MyModel.remoteMethod('postSomething', {
accepts: [
{
arg: 'person',
type: {
name: 'string',
credentials: {
type: {
user: 'string',
pass: 'string'
}
}
},
http: {
source: 'body'
},
required: true
}
],
//...
This also works with arrays:
accepts: [
{
arg: 'Book',
type: {
title: 'string',
author: 'string',
pages: [{
type: {
pageNo: 'number',
text: 'string'
}
}]
}
}
],
// ...
Loopback 3.x
Since the model registry and strong remoting changed in Loopback 3.x to only allow string or array types, you can't really avoid creating a new model. If you would like to quickly 'inline' a model without going through the full process of adding the model json file, adding it to model-config.json etc. you can register it directly on the app:
app.registry.createModel('Person', {
firstName: 'string',
lastName: 'string'
}, { base: 'Model' });
You can set the base to one of your other models if you want to extend an existing model (e.g, add another property that is only accepted in the given remote method)
If you want to create the model without cluttering up your model registry, you can do so by calling createModel on loobpack itself:
const loopback = require('loopback')
const modl = loopback.createModel({
name: 'Person',
base: null,
properties: {
firstName: {
type: 'string',
id: true // means it won't have an id property
}
}
});
In both of the above examples, you refer to the model by name to attach it to the remote method:
accepts: [
{
arg: 'Person',
type: 'Person'
}
],
// ...
Note you will need to create a sub-model for every sub-property (e.g. credentials)
Loopback swagger only picks up the outer object ignoring the properties of the object.
If you want to show a nested object in the swagger docs for the request body, you will have to make nested model.
Assuming you have a model called as person. You have to create another model named "credentials" having properties user and password. Then define the relationship in your person model's config
{
"name": "Person",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"credentials": {
"type": "embedsOne",
"model": "credentials",
"property": "credentials",
"options": {
"validate": true,
"forceId": false
}
}
},
"acls": [],
"methods": {}
}
And add a reference to this model where you define your remote method
MyModel.remoteMethod("postSomething", {
accepts: [
{arg: 'person', type: {Person},
http: {source: 'body'}, required: true
}
],
To avoid "Treating unknown remoting type" warning make sure your model is marked as "public" inside your "model-config.json"

how to get value from json file using jquery autocomplete

This is my jquery code
$('.typeahead', this).autocomplete({
source: function(request, response) {
$.ajax({
url: 'includes/stations.json',
dataType: 'json',
data: request,
success: function(data) {
response($.map(data, function(item, i) {
return {
label: item.name,
value: item.code
}
}));
},
});
},
minLength: 3
});
My Json File is
[
{
"code": "9BP3",
"name": "9Bp No3"
},
{
"code": "AA",
"name": "Ataria"
},{
"code": "BILA",
"name": "Bheslana"
},
{
"code": "BILD",
"name": "Bildi"
},{
"code": "HRI",
"name": "Hardoi"
},
{
"code": "HRM",
"name": "Hadmadiya"
}
]
When i typing any three letter its returns whole json file values
q: request.term this is the string for filter returned values from stations.json. You must pass variable like this to filter results. stations.json must be dynamically generated file like php with json header. q is $_GET parameter and must be parsed. Try to change the code like this:
$.ajax({
url: "includes/stations.json",
dataType: "json",
data: {
q: request.term // here is the string for filter returned values from stations.json. You must pass variable like this to filter results. stations.json must be dynamically generated file like php with json header. q is $_GET parameter and must be parsed.
},
success: function(data) {
response(
$.map(data, function(item, i) {
return {
label: item.name,
value: item.code
}
})
);
}
});
},
minLength: 3,

Resources