janusgraph with createing the same garph in different time - janusgraph

In this case,first , i opende a janusgraph ,created some vertexes and edges
and closed it;later,i opened the same janusgraph,create some vertexes and edges
and closed it.
After all,i want to find the pathes form a vertex to another ,i find that the two vertexes are not in one path ,because they created in different time;however,if i create them together ,the path is right.
here are some codes for creating:
val grap = JanusGraphFactory.open("d:\\janusgraph\\janusgraph-hbase.properties")
val mgmt = grap.openManagement()
mgmt.makePropertyKey("value").dataType(classOf[String]).make()
mgmt.makeEdgeLabel("deviceid").make()
mgmt.makeVertexLabel("phone").make()
val tx = grap.newTransaction()
val phone1 = tx.addVertex(T.label, "phone", "value", "13700000001")
val phone2 = tx.addVertex(T.label, "phone", "value", "13700000002")
val phone3 = tx.addVertex(T.label, "phone", "value", "13700000003")
val phone4 = tx.addVertex(T.label, "phone", "value", "13700000004")
val phone5 = tx.addVertex(T.label, "phone", "value", "13700000005")
val dev1 = tx.addVertex(T.label, "dev", "value", "dev1")
val dev2 = tx.addVertex(T.label, "dev", "value", "dev2")
val dev3 = tx.addVertex(T.label, "dev", "value", "dev3")*/
phone1.addEdge("phone-dev", dev1, "value", "13700000001_dev1")
phone2.addEdge("phone-dev", dev1, "value", "13700000002_dev1")
phone2.addEdge("phone-dev", dev2, "value", "13700000002_dev2")
phone3.addEdge("phone-dev", dev2, "value", "13700000003_dev2")
phone4.addEdge("phone-dev", dev2, "value", "13700000004_dev2")
phone4.addEdge("phone-dev", dev3, "value", "13700000004_dev3")
tx.commit()
tx.close()
here are codes for finding:
val graph = JanusGraphFactory.open("d:\\janusgraph\\janusgraph-hbase.properties")
//val graph = JanusGraphFactory.open(configuration)
val g = graph.traversal()
val result2 = g.V().hasLabel("phone").repeat(both().simplePath()).until(bothE().count().is(1)).path().by("value").toSet
//val result = g.V().hasLabel("phone").repeat(both().simplePath()).until(bothE().count().is(1)).path().by
val it = result2.iterator()
while (it.hasNext) {
println("path=>" + it.next())
}
System.exit(1)

JanusGraph have something called Transactional Scope. According to this concept,
All graph elements (vertices, edges, and types) are associated with the transactional scope in which they were retrieved or created. Under TinkerPop’s default transactional semantics, transactions are automatically created with the first operation on the graph and closed explicitly using commit() or rollback(). Once the transaction is closed, all graph elements associated with that transaction become stale and unavailable. However, JanusGraph will automatically transition vertices and types into the new transactional scope as shown in this example:
graph = JanusGraphFactory.open("berkeleyje:/tmp/janusgraph")
juno = graph.addVertex() //Automatically opens a new transaction
graph.tx().commit() //Ends transaction
juno.property("name", "juno") //Vertex is automatically transitioned
Edges, on the other hand, are not automatically transitioned and cannot be accessed outside their original transaction. They must be explicitly transitioned:
e = juno.addEdge("knows", graph.addVertex())
graph.tx().commit() //Ends transaction
e = g.E(e).next() //Need to refresh edge
e.property("time", 99)

Related

Get data from 4 tables in Android Room

I'm trying to get data from the database using Room, I want to get the data in the format {registration_number, List, List} but I'm getting an error:
"Cannot find the parent entity column area_name in ... and my intermediate class"
and in fact I hide that maybe I am taking the wrong approach, please guide me, because I am new in this area
to extract the data I use an intermediate class
my class is:
data class LastConfiscats(
#ColumnInfo(name = "registration_number")
var slaugh_num: String,
// #ColumnInfo(name = "area_name",
#Relation(entity = Area::class, parentColumn = "area_name", entityColumn = "name")
var areaName: List<String>,
// #ColumnInfo(name = "confiscation_name")
#Relation(entity = Confiscation::class, parentColumn = "confiscation_name", entityColumn = "name")
var confiscationName: List<String>
and DAO method to select data:
#Query("SELECT registration_number, area.[name] AS area_name, confiscations.[name] AS confiscation_name " +
"FROM car_body, car_body_confiscations" +
"INNER JOIN area ON car_body_confiscations.area_id == area.id " +
"INNER JOIN confiscations ON car_body_confiscations.confiscation_id == confiscations.id " +
"WHERE car_body.id == car_body_confiscations.car_body_id ORDER BY car_body.id DESC LIMIT :row_count")
fun getLastConfiscats(row_count: Int): LiveData<List<LastConfiscats>>
The linkage scheme between the tables that I am trying to implement is as follows:
There are examples on the internet how to make a relationship between 2 tables but I need to create a relationship between 4 tables.
Please help me to get the data in the right way
UPDATE :
My Area entity is:
#Entity(tableName = "area")
data class Area( #PrimaryKey(autoGenerate = true) var id: Int?, var name: String? )
but in my Confiscation entity I also have "name" column:
#Entity(tableName = "confiscations")
data class Confiscation( #PrimaryKey(autoGenerate = true) var id: Int?, var name: String? )
The actual message you are getting is because when you use #Relation the parent MUST exist and be annotated with #Embedded.
The parent and entity columns MUST be columns in the respective classes.
As an example the following will enable you to get a List of Confiscations, with the related CarBody and the respective Areas (note colum names based upon the screen shots):-
data class LastConfiscats(
#Embedded
var carBodyConfiscations: Car_Body_Confiscations,
#Relation(entity = CarBody::class, parentColumn = "car_body_id", entityColumn = "id")
var carBody: CarBody,
#Relation(entity = Area::class, parentColumn = "areaId", entityColumn = "id")
var area: List<Area>
)
You could use the above with a query such as:-
#Query("SELECT * FROM Car_Body_Confiscations")
fun getCardBodyJoinedWithStuff(): List<LastConfiscats>
No JOINS needed. That is because Room builds the underlying SQL. First is basically the copy of the supplied query. After retrieving the Car_Body_Confiscations it then uses queries based upon the field names/#ColumnInfo and runs queries for each Car_Body_Connfiscation.
For each #Relationship it populates the respective fields (1 carBody and the List of Areas) using queries that it builds. Here's and example of part of the code, for the above from the java(generated) for the query above :-
Main (parent query)
#Override
public List<LastConfiscats> getCardBodyJoinedWithStuff() {
final String _sql = "SELECT * FROM Car_Body_Confiscations";
final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
....
Later Nn (getting the CarBody(s) there will only be 1)
StringBuilder _stringBuilder = StringUtil.newStringBuilder();
_stringBuilder.append("SELECT `id`,`registrationNumber`,`datetime`,`userId`,`testId` FROM `CarBody` WHERE `id` IN (");
final int _inputSize = _map.size();
Even Later On (Areas)
StringBuilder _stringBuilder = StringUtil.newStringBuilder();
_stringBuilder.append("SELECT `id`,`name` FROM `Area` WHERE `id` IN (");
Now if you want to code your own JOINS etc and alias columns then you will have to consider a few things.
The receiving class MUST be able to be built from the result set and thus column names MUST match the fields in the POJO (unless using #Prefix annotation).
You also need to be aware that the result set will be the cartesian product, thus in the case of doing the above, bypassing how Room does it, the for each combination/permutation of confiscation/carbody/area you get a row (unless grouped/excluded by where clause). So if you have 1 confiscation joined to 1 car but with 10 areas then you would get 10 rows all with the same confiscation and carbody.
You may wish to consider having a look at Room #Relation annotation with a One To Many relationship. Which explains this a little more and includes an example of using a JOINs
Additional - User and TestLists
You may well want to include the CarBody's User and the Test_Lists so you have a result with all of the related data.
This needs to be looked at from a hierarchical perspective. That is the confiscation has a direct link/reference/map to the CarBody but underneath that are the links/references/mappings to the User from the CarBody and to the Test_Lists.
So to incorporate this you need a POJO for a CarBody with it's User and it's Test_Lists. So, for example:-
data class CarBodyWithUserAndWithTestList(
#Embedded
var carBody: CarBody,
#Relation(
entity = Users::class,
parentColumn = "userId",
entityColumn = "id"
)
var users: Users,
#Relation(
entity = Test_List::class,
parentColumn = "testId",
entityColumn = "id"
)
var testList: List<Test_List>
)
With this you can then amend the LastConfiscats to include a CarBodyWithUserAndWithTestList instead of just a CarBody e.g.:
data class LastConfiscats(
#Embedded
var carBodyConfiscations: Car_Body_Confiscations,
#Relation(entity = CarBody::class, parentColumn = "car_body_id", entityColumn = "id")
//var carBody: CarBody, /* REMOVED */
var carBodyWithUserAndWithTestList: CarBodyWithUserAndWithTestList, /* ADDED */
#Relation(entity = Area::class, parentColumn = "areaId", entityColumn = "id")
var area: List<Area>
)
Note that the #Relation has the CarBody class as the entity. That is because the CarBody is the class that needs to be inspected in order for Room to ascertain the columns used for the links/references/,mappings.
*Working Example/Demo
Here's the entire code for a Working example that inserts some data into all the tables and then extracts the data using the getCardBodyJoinedWithStuff query, it then writes the data to the Log.
the code includes ForeignKey constraints which enforces and helps to maintain referential integrity.
for id's Long rather than Int has been used as Long properly reflects the potential size of the field/value.
autoGenerate = true has not been used as this is inefficient and not needed see https://sqlite.org/autoinc.html, which includes as the very first statement The AUTOINCREMENT keyword imposes extra CPU, memory, disk space, and disk I/O overhead and should be avoided if not strictly needed. It is usually not needed. (autoGenerate = true results in AUTOINCREMENT)
So all the classes/interfaces :-
#Entity(
foreignKeys = [
ForeignKey(
Users::class,
parentColumns = ["id"],
childColumns = ["userId"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
),
ForeignKey(
Test_List::class,
parentColumns = ["id"],
childColumns = ["testId"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
)
]
)
data class CarBody(
#PrimaryKey
var id: Long?=null,
var registrationNumber: Int,
var datetime: String,
#ColumnInfo(index = true)
var userId: Long,
#ColumnInfo(index = true)
var testId: Long
)
#Entity
data class Users(
#PrimaryKey
var id:Long?=null,
var name: String,
var lastName: String,
var email: String,
var password: String
)
#Entity
data class Test_List(
#PrimaryKey
var id: Long?=null,
var date: String,
var is_saved: Boolean
)
#Entity(
foreignKeys = [
ForeignKey(
entity = CarBody::class,
parentColumns = ["id"],
childColumns = ["car_body_id"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
),
ForeignKey(
entity = Confiscation::class,
parentColumns = ["id"],
childColumns = ["confiscation_id"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
),
ForeignKey(
entity = Area::class,
parentColumns = ["id"],
childColumns = ["areaId"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
)
]
)
data class Car_Body_Confiscations(
#PrimaryKey
var id: Long?=null,
#ColumnInfo(index = true)
var car_body_id: Long,
#ColumnInfo(index = true)
var confiscation_id: Long,
#ColumnInfo(index = true)
var areaId: Long
)
#Entity
data class Area(
#PrimaryKey
var id: Long?=null,
var name: String
)
#Entity
data class Confiscation(
#PrimaryKey
var id: Long?=null,
var name: String
)
#Dao
interface AllDao {
#Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(area: Area): Long
#Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(carBodyConfiscations: Car_Body_Confiscations): Long
#Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(carBody: CarBody): Long
#Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(confiscation: Confiscation): Long
#Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(users: Users): Long
#Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(testList: Test_List): Long
#Transaction
#Query("SELECT * FROM Car_Body_Confiscations")
fun getCardBodyJoinedWithStuff(): List<LastConfiscats>
}
#Database(entities = [
Area::class,
Car_Body_Confiscations::class,
CarBody::class,
Confiscation::class,
Users::class,
Test_List::class
],
exportSchema = false, version = 1)
abstract class TheDatabase: RoomDatabase() {
abstract fun getAllDao(): AllDao
companion object {
private var instance: TheDatabase?=null
fun getInstance(context: Context): TheDatabase {
if (instance==null) {
instance = Room.databaseBuilder(context,TheDatabase::class.java,"the_database.db")
.allowMainThreadQueries()
.build()
}
return instance as TheDatabase
}
}
}
data class LastConfiscats(
#Embedded
var carBodyConfiscations: Car_Body_Confiscations,
#Relation(entity = Confiscation::class, parentColumn = "confiscation_id", entityColumn = "id")
var confiscation: Confiscation,
#Relation(entity = CarBody::class, parentColumn = "car_body_id", entityColumn = "id")
//var carBody: CarBody, /* REMOVED */
var carBodyWithUserAndWithTestList: CarBodyWithUserAndWithTestList, /* ADDED */
#Relation(entity = Area::class, parentColumn = "areaId", entityColumn = "id")
var area: List<Area>
)
data class CarBodyWithUserAndWithTestList(
#Embedded
var carBody: CarBody,
#Relation(
entity = Users::class,
parentColumn = "userId",
entityColumn = "id"
)
var users: Users,
#Relation(
entity = Test_List::class,
parentColumn = "testId",
entityColumn = "id"
)
var testList: List<Test_List>
)
The following activity code (note that main thread used for brevity and convenience):-
class MainActivity : AppCompatActivity() {
lateinit var db: TheDatabase
lateinit var dao: AllDao
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = TheDatabase.getInstance(this)
dao = db.getAllDao()
dao.insert(Users(100,"Fred","Bloggs","fredBloggs#mail.com","password"))
dao.insert(Users(200,"Jane","Doe","janeDoe#email.org","password"))
/* example where id is autogenerated */
val marySmithId = dao.insert(Users(name = "Mary", lastName = "Smith", email = "marysmith#mailit.co.uk", password = "1234567890"))
dao.insert(Test_List(1,"2022-01-01",false))
dao.insert(Test_List(2,"2022-02-02",true))
dao.insert(CarBody(1000,1234,"2022-01-01",100 /* Fred Bloggs*/,2 ))
dao.insert(CarBody(2000,4321,"2021-12-05",100,1))
dao.insert(CarBody(3000,1111,"2021-09-10",200,2))
dao.insert(Area(100,"Area100"))
dao.insert(Area(200,"Area200"))
dao.insert(Area(300,"Area300"))
dao.insert(Area(400,"Area400"))
dao.insert(Confiscation(901,"C1"))
dao.insert(Confiscation(902,"C2"))
dao.insert(Confiscation(903,"C3"))
dao.insert(Confiscation(904,"C4"))
dao.insert(Car_Body_Confiscations(500,1000,901,100))
dao.insert(Car_Body_Confiscations(510,2000,904,400))
dao.insert(Car_Body_Confiscations(520,3000,902,300))
/* Extract the data and output to the Log */
for(cbc in dao.getCardBodyJoinedWithStuff()) {
val areaList = StringBuilder()
for (a in cbc.area) {
areaList.append("\n\t\tArea is ${a.name} ID is ${a.id}")
}
val testList = StringBuilder()
testList.append("\n\t\tThere are ${cbc.carBodyWithUserAndWithTestList.testList.size} TestLists, they are:")
for (t in cbc.carBodyWithUserAndWithTestList.testList) {
testList.append("\n\t\t\t${t.date} Save is ${t.is_saved} ID is ${t.id}")
}
Log.d(
"DBINFO",
"CBC ID =${cbc.carBodyConfiscations.id}" +
"\n\tConfiscation Name is ${cbc.confiscation.name}" +
"\n\tAreas (there is/are ${cbc.area.size}) they are $areaList}" +
"\n\tCarBody Reg is ${cbc.carBodyWithUserAndWithTestList.carBody.registrationNumber} " +
"Date is ${cbc.carBodyWithUserAndWithTestList.carBody.datetime}" +
"\n\t\tUser is ${cbc.carBodyWithUserAndWithTestList.users.name}" +
",${cbc.carBodyWithUserAndWithTestList.users.lastName} " +
"email is ${cbc.carBodyWithUserAndWithTestList.users.email}" +
"$testList"
)
}
}
}
Result
The Log after running:-
D/DBINFO: CBC ID =500
Confiscation Name is C1
Areas (there is/are 1) they are
Area is Area100 ID is 100}
CarBody Reg is 1234 Date is 2022-01-01
User is Fred,Bloggs email is fredBloggs#mail.com
There are 1 TestLists, they are:
2022-02-02 Save is true ID is 2
D/DBINFO: CBC ID =510
Confiscation Name is C4
Areas (there is/are 1) they are
Area is Area400 ID is 400}
CarBody Reg is 4321 Date is 2021-12-05
User is Fred,Bloggs email is fredBloggs#mail.com
There are 1 TestLists, they are:
2022-01-01 Save is false ID is 1
D/DBINFO: CBC ID =520
Confiscation Name is C2
Areas (there is/are 1) they are
Area is Area300 ID is 300}
CarBody Reg is 1111 Date is 2021-09-10
User is Jane,Doe email is janeDoe#email.org
There are 1 TestLists, they are:
2022-02-02 Save is true ID is 2
Re the Comment
I actually have a Cartesian product, I had to process it somehow, although I do not know how yet.
You may find that the above is fine and processes the product pretty easily.
Where Room's relationship handling can become restrictive is if you want to selectively retrieve related data. The way Room handles #Relation means that it retrieves ALL children irrespective of any JOINS and WHERE clauses. They are only effective if they affect the result of the topmost parent.
In your case, where you don't actually cater for lists (such as multiple users per carbody) then Room should suffice.
The original Query - revisited
Changing your query a little to (largely to suit the previous classes ) to:-
#Query("SELECT " +
"registrationNumber, " +
"area.[name] AS area_name, " +
"confiscation.[name] AS confiscation_name " +
"FROM carbody, car_body_confiscations " +
"INNER JOIN area ON car_body_confiscations.areaId == area.id " +
"INNER JOIN confiscation ON car_body_confiscations.confiscation_id == confiscation.id " +
"WHERE carbody.id == car_body_confiscations.car_body_id " +
"ORDER BY carbody.id DESC " +
"LIMIT :row_count"
)
fun getLastConfiscats(row_count: Int): /*LiveData<*/List<MyQueryPOJO>/*>*/
see the following re MyQueryPOJO
And adding a suitable class (no #Embeddeds or #Relations needed, so Room doesn't get confused with column names) :-
data class MyQueryPOJO(
/* The output columns of the query */
var registrationNumber: Int,
#ColumnInfo(name = "area_name")
var not_the_area_name: String,
var confiscation_name: String
)
note how the not_the_area_name field has the #ColumnInfo annotation to tell it to use the area_name output column
In the activity, using:-
for (mqo in dao.getLastConfiscats(10)) {
Log.d("DBINFO","Reg = ${mqo.registrationNumber} Confiscation = ${mqo.confiscation_name} Area Name = ${mqo.not_the_area_name}")
}
Results in (with the same data) :-
D/DBINFO: Reg = 1111 Confiscation = C2 Area Name = Area300
D/DBINFO: Reg = 4321 Confiscation = C4 Area Name = Area400
D/DBINFO: Reg = 1234 Confiscation = C1 Area Name = Area100
as the relationships all all basically 1-1 (the references are back to front for a 1-many) the cartesian product is fine as there will not be any duplicates.

Spring boot Neo4j - query depth not working correctly

TL;DR: #Depth(value = -1) throws nullpointer and other values above 1 are ignored
In my Spring Boot with Neo4j project I have 3 simple entities with relationships:
#NodeEntity
data class Metric(
#Id #GeneratedValue val id: Long = -1,
val name: String = "",
val description: String = "",
#Relationship(type = "CALCULATES")
val calculates: MutableSet<Calculable> = mutableSetOf()
) {
fun calculates(calculable: Calculus) = calculates.add(calculable)
fun calculate() = calculates.map { c -> c.calculate() }.sum()
}
interface Calculable {
fun calculate(): Double
}
#NodeEntity
data class Calculus(
#Id #GeneratedValue val id: Long = -1,
val name: String = "",
#Relationship(type = "LEFT")
var left: Calculable? = null,
#Relationship(type = "RIGHT")
var right: Calculable? = null,
var operator: Operator? = null
) : Calculable {
override fun calculate(): Double =
operator!!.apply(left!!.calculate(), right!!.calculate())
}
#NodeEntity
data class Value(
#Id #GeneratedValue val id: Long = -1,
val name: String = "",
var value: Double = 0.0
) : Calculable {
override fun calculate(): Double = value
}
enum class Operator : BinaryOperator<Double>, DoubleBinaryOperator {//not relevant}
I create a simple graph like this one:
With the following repositories:
#Repository
interface MetricRepository : Neo4jRepository<Metric, Long>{
#Depth(value = 2)
fun findByName(name: String): Metric?
}
#Repository
interface CalculusRepository : Neo4jRepository<Calculus, Long>{
fun findByName(name: String): Calculus?
}
#Repository
interface ValueRepository : Neo4jRepository<Value, Long>{
fun findByName(name: String): Value?
}
And the following code:
// calculus
val five = valueRepository.save(Value(
name = "5",
value = 5.0
))
val two = valueRepository.save(Value(
name = "2",
value = 2.0
))
val fiveTimesTwo = calculusRepository.save(Calculus(
name = "5 * 2",
operator = Operator.TIMES,
left = five,
right = two
))
println("---")
println(fiveTimesTwo)
val fromRepository = calculusRepository.findByName("5 * 2")!!
println(fromRepository) // sometimes has different id than fiveTimesTwo
println("5 * 2 = ${fromRepository.calculate()}")
println("--- \n")
// metric
val metric = metricRepository.save(Metric(
name = "Metric 1",
description = "Measures a calculus",
calculates = mutableSetOf(fromRepository)
))
metricRepository.save(metric)
println("---")
println(metric)
val metricFromRepository = metricRepository.findByName("Metric 1")!!
println(metricFromRepository) // calculates node is partially empty
println("--- \n")
To retrieve the same graph as shown in the picture above (taken from the actual neo4j dashboard), I do metricRepository.findByName("Metric 1") which has #Depth(value = 2) and then print the saved metric and the retrieved metric:
Metric(id=9, name=Metric 1, description=Measures a calculus, calculates=[Calculus(id=2, name=5 * 2, left=Value(id=18, name=5, value=5.0), right=Value(id=1, name=2, value=2.0), operator=TIMES)])
Metric(id=9, name=Metric 1, description=Measures a calculus, calculates=[Calculus(id=2, name=5 * 2, left=null, right=null, operator=TIMES)])
No matter the value of the depth, I can't get the Metric node with all his children nodes, it retrieves one level deep max and returns null on the leaf nodes.
I've read in the docs that depth=-1 retrieves the fully-resolved node but doing so causes the findByName() method to fail with a null pointer: kotlin.KotlinNullPointerException: null
Here is a list of resources I've consulted and a working GitHub repository with the full code:
GitHub Repo
Spring Data Neo4j Reference Documentation
Neo4j-OGM Docs
Final notes:
The entities all have default parameters because Kotlin then makes an empty constructor, I think the OGM needs it
I've also tried making custom queries but couldn't specify the depth value because there are different relationships and can be at different levels
To use the GitHub repository I linked you must have Neo4j installed, the repo has a stackoverflow-question branch with all the code.
Versions:
Spring boot: 2.3.0.BUILD-SNAPSHOT
spring-boot-starter-data-neo4j: 2.3.0.BUILD-SNAPSHOT
Thank you for helping and all feedback is welcomed!
The problem is not with the query depth but with the model. The Metric entity has a relation with Calculable, but Calculable itself has no relationships defined. Spring Data cannot scan all possible implementations of the Calculable interface for their relationships. If you changed Metrics.calculates type to MutableSet<Calculus>, it would work as expected.
To see Cypher requests send to the server you can add logging.level.org.neo4j.ogm.drivers.bolt=DEBUG to the application.properties
Request before the change:
MATCH (n:`Metric`) WHERE n.`name` = $`name_0` WITH n RETURN n,[ [ (n)->[r_c1:`CALCULATES`]->(x1) | [ r_c1, x1 ] ] ], ID(n) with params {name_0=Metric 1}
Request after the change:
MATCH (n:`Metric`) WHERE n.`name` = $`name_0` WITH n RETURN n,[ [ (n)->[r_c1:`CALCULATES`]->(c1:`Calculus`) | [ r_c1, c1, [ [ (c1)-[r_l2:`LEFT`]-(v2:`Value`) | [ r_l2, v2 ] ], [ (c1)-[r_r2:`RIGHT`]-(v2:`Value`) | [ r_r2, v2 ] ] ] ] ] ], ID(n) with params {name_0=Metric 1}

Meaning of Payload-LINQ

I am new for LINQ, the above code is executing fine for me.
But I couldn't figure out why in the last sentence c.payload.Quantity is written instead of c.Quantity.
When I googled I came to know that the value Quantity is obtained from the payload that we get from the results in c, does that mean that the payload is the final output of filterQuery?
var orderData = new[]
{
new {OrderDate = new DateTime(2011,1,1,8,30,00), ItemID = "100", UnitPrice = 0.99, Quantity =5},
new {OrderDate = new DateTime(2011,1,1,8,31,00), ItemID = "200", UnitPrice = 3.99, Quantity =2},
new {OrderDate = new DateTime(2011,1,1,9,02,00), ItemID = "200", UnitPrice = 1.50, Quantity =1},
new {OrderDate = new DateTime(2011,1,1,9,07,00), ItemID = "100", UnitPrice = 4.10, Quantity =3}
};
var orders = orderData.ToPointStream(Application,ev=>PointEvent.CreateInsert(ev.OrderDate,ev),AdvanceTimeSettings.StrictlyIncreasingStartTime);
var filterQuery = from o in orders where o.Quantity>=2 select o;
(from o in filterQuery.ToIntervalEnumerable() where o.EventKind == EventKind.Insert
select new {o.StartTime,o.EndTime,o.Payload.Quantity}).Dump("Heading");
ToIntervalEnumerable transitions from the StreamInsight APIs and event model to a plain old .NET sequence. in the latter, in addition to the payload, you can access the system fields StartTime, EndTime, and EventKind. To avoid naming conflicts, the payload needs to be encapsulated (imagine the payload, which is defined by the user, had a field 'StartTime'!). this is the meaning of the Payload field.

asp.net mvc3, why my dropdownlist is not selected?

I create my selectlist from enum.
[Flags]
public enum Age
{
New_Born = 1,
Toddler = 2,
Preschool = 4,
Kindergarten = 8,
Elementary_School = 16,
Middle_School = 32,
High_School = 64
}
var age = from Age e in Enum.GetValues(typeof(Age))
select new { Id = (int)e, Name = e.ToString().Replace("_", " ") };
I tried both:
var ageList = new SelectList(age, "Id", "Name", (int)Model.Child.Age);
or
var ageList = new SelectList(age, "Id", "Name", Model.Child.Age);
#Html.DropDownListFor(m => m.Child.Age, ageList, "Your Child's Age")
Everything works except the selected value didn't get selected.
EDIT: after hours testing, finally fix it.
chagne Id = (int)e to Id = e.
var age = from Age e in Enum.GetValues(typeof(Age))
select new { Id = e, Name = e.ToString().Replace("_", " ") };
var ageList = new SelectList(age, "Id", "Name", Model.Child.Age);
I just created a similar example and worked out your problem and I believe you have two problems with your code:
In your controller code, you should have your first option, like this:
SelectList selectList = new SelectList(items, "Id", "Name", (int)Qualities.Whatever);
And in your view:
<%= this.Html.DropDownListFor(m => m.List.SelectedValue, this.Model.List, "Qualities") %>
Think about it, why would you pass the SelectList twice? You should pass the selected value and then the list of values.
The fact that I didn't use Razor view engine is irrelevant.
after hours testing, finally fix it. chagne Id = (int)e to Id = e.
var age = from Age e in Enum.GetValues(typeof(Age))
select new { Id = e, Name = e.ToString().Replace("_", " ") };
var ageList = new SelectList(age, "Id", "Name", Model.Child.Age);

Linq "reporting" question with list properties

I have an entity object that contains a list property. I'd like to expand the list values to the right. Being new to LINQ, I'm not sure how to do this. I could strongly type an object, but then I'd have to know the count/values at compile time and I'd like to make it more dynamic.
The output that I'm wanting is something like:
Name Demo1 Demo2 Demo3
Person Name1 TX TX
Person Name2 TX OK
Person Name3 TX TX OK
Main Class
public Main()
{
List<Event> events = new List<Event>();
events.Add(new Event()
{
EventDate = DateTime.Now,
EventLocation = new Location() { State = "TX" },
EventName = "Demo1"
});
events.Add(new Event()
{
EventDate = DateTime.Now,
EventLocation = events[0].EventLocation,
EventName = "Demo2"
});
events.Add(new Event()
{
EventDate = DateTime.Now,
EventLocation = new Location() { State = "OK" },
EventName = "Demo3"
});
List<Person> people = new List<Person>();
Person person1 = new Person();
person1.Name = "Person Name1";
person1.Events.Add(events[0]);
person1.Events.Add(events[1]);
Person person2 = new Person();
person2.Name = "Person Name2";
person2.Events.Add(events[0]);
person2.Events.Add(events[2]);
Person person3 = new Person();
person3.Name = "Person Name3";
person3.Events.Add(events[0]);
person3.Events.Add(events[1]);
person3.Events.Add(events[2]);
people.Add(person1);
people.Add(person2);
people.Add(person3);
}
It depends on whether you want to run the query in memory or in databse. In any case, you'll need to return a list with the "dynamic" part of the results, because you cannot dynamically generate members of anonymous types (and working with them would be difficult).
In memory (as in your example), you can write the following query:
// Find names of all events (for all people)
var allNames =
(from p in people
from e in p.Events
select e.EventName).Distinct();
// Find events for every person
var res =
from p in people
let known = p.Events.ToDictionary(e => e.EventName)
select new {
p.Name,
Events = allNames.Select(n =>
known.ContainsKey(n)?known[n].EventLocation:"N/A")
};
The first query gets names of all events (we use it later to find a value for all event for every person). The second query iterates over all people. It first creates dictionary with events (for fast lookup in memory) and then iterates over all event names and tries to find them in the dictionary (returning "N/A" if it is not found).

Resources