How to create query for elasticsearch by spring-data-elasticsearch - spring-data-elasticsearch

I hope to execute a query and the condition is that one field not existing. I only know that we are able to use exists() to retrieve the data when the field existing. But I cannot find any api for no field existing case.
[Query Example]
Criteria criteria = new Criteria();
criteria.and(new Criteria("field_a").exists());
CriteriaQuery criteriaQuery = new CriteriaQuery(criteria);
elasticsearchRestTemplate.search(criteriaQuery, OrderLine.class);
Could you please advise how I should use the spring-data-elasticsearch api

Just add not() to the criteria:
criteria.and(new Criteria("field_a").exists().not());

Related

Mongo Template : Modifying Match Operation dynamically

I have defined my match operation in mongo template as below.
MatchOperation match = Aggregation.match(new Criteria("workflow_stage_current_assignee").ne(null)
.andOperator(new Criteria("CreatedDate").gte(new Date(fromDate.getTimeInMillis()))
.andOperator(new Criteria("CreatedDate").lte(new Date(toDate.getTimeInMillis())))));
Everything is fine until this. However I can not modify this match operation using the reference match I have created. I was looking for List kind of functionality where in I could add multiple criteria clauses as and when they are needed to an already created reference. Something on the lines match.add(new Criteria)
However MatchOperation currently does not support any methods which would provide this functionality. Any help in this regard would be appreciated.
Criteria is where you add new criteria, which is backed by list.
Use static Criteria where(String key) method to create a initialize criteria object.
Something like
Criteria criteria = where("key1").is("value1");
Add more criteria's
criteria.and("key2").is("value2");
Create implicit $and criteria and chain to existing criteria chain.
criteria.and(where("key3).gt(value3).lte(value4))
When you are done, just pass it to match operation.
MatchOperation match = Aggregation.match(criteria);

Is there a way to save a WIQL query on the TFS Server?

Hopefully the title says it all. I've retrieved the results of adhoc queries using the WorkItemStore.Query() method and created Query objects via the new syntax. However after examining the object model for Query objects, QueryFolders, QueryItems and the WorkItemStore I can't find a way to create and save a WIQL query to the store/TFS Server.
Any suggestions?
You can use QueryHierarchy.Save Method to save the query. For example:
QueryDefinition query = new QueryDefinition("My Query", "Select * from WorkItems Where [System.AssignedTo] = #me", parentFolder);
myproject.QueryHierarchy.Save();
Check blog for more information: http://blogs.msdn.com/b/team_foundation/archive/2010/06/16/work-item-tracking-queries-object-model-in-2010.aspx

Create Node and Relationship in one query : Spring Data Neo4j

I am trying to create new nodes and relationships using Neo4j using Spring Data Neo4j. My use case is to add a friend relationship between 2 user nodes. So this boils down to :
User user1 = userRepo.findByPropertyValue("userId1", userId1);
User user2 = userRepo.findByPropertyValue("userId2", userId2);
if(user1 == null){
createUserObject(userId1);
}
if(user2 == null){
createUserObject(userId2);
}
user1.isFriend(user2);
userRepo.save();
So this includes 2 calls to the DB (findByPropertyValue). Is this correct or is there another way to do this ? Maybe batch the whole thing up into one request ?
Thanks..
You can do both with a single cypher query:
START user1=node:User(userId={userId1}),
user2=node:User(userId={userId2})
CREATE UNIQUE (user1)-[:FRIEND]-(user2);
The user-id's are passed in as params in a map.
You can also use an annotated repository method for that.

Neo4j indexes and legacy data

I have a legacy dataset (ENRON data represented as GraphML) that I would like to query. In an comment in a related question, #StefanArmbruster suggests that I use Cypher to query the database. My query use case is simple: given a message id (a property of the Message node), retrieve the node that has that id, and also retrieve the sender and recipient nodes of that message.
It seems that to do this in Cypher, I first have to create an index of the nodes. Is there a way to do this automatically when the data is loaded from the graphML file? (I had used Gremlin to load the data and create the database.)
I also have an external Lucene index of the data (I need it for other purposes). Does it make sense to have two indexes? I could, for example, index the Neo4J node ids into my external index, and then query the graph based on those ids. My concern is about the persistence of these ids. (By analogy, Lucene document ids should not be treated as persistent.)
So, should I:
Index the Neo4j graph internally to query on message ids using Cypher? (If so, what is the best way to do that: regenerate the database with some suitable incantation to get the index built? Build the index on the already-existing db?)
Store Neo4j node ids in my external Lucene index and retrieve nodes via these stored ids?
UPDATE
I have been trying to get auto-indexing to work with Gremlin and an embedded server, but with no luck. In the documentation it says
The underlying database is auto-indexed, see Section 14.12, “Automatic Indexing” so the script can return the imported node by index lookup.
But when I examine the graph after loading a new database, no indexes seem to exist.
The Neo4j documentation on auto indexing says that a bunch of configuration is required. In addition to setting node_auto_indexing = true, you have to configure it
To actually auto index something, you have to set which properties
should get indexed. You do this by listing the property keys to index
on. In the configuration file, use the node_keys_indexable and
relationship_keys_indexable configuration keys. When using embedded
mode, use the GraphDatabaseSettings.node_keys_indexable and
GraphDatabaseSettings.relationship_keys_indexable configuration keys.
In all cases, the value should be a comma separated list of property
keys to index on.
So is Gremlin supposed to set the GraphDatabaseSettings parameters? I tried passing in a map into the Neo4jGraph constructor like this:
Map<String,String> config = [
'node_auto_indexing':'true',
'node_keys_indexable': 'emailID'
]
Neo4jGraph g = new Neo4jGraph(graphDB, config);
g.loadGraphML("../databases/data.graphml");
but that had no apparent effect on index creation.
UPDATE 2
Rather than configuring the database through Gremlin, I used the examples given in the Neo4j documentation so that my database creation was like this (in Groovy):
protected Neo4jGraph getGraph(String graphDBname, String databaseName) {
boolean populateDB = !new File(graphDBName).exists();
if(populateDB)
println "creating database";
else
println "opening database";
GraphDatabaseService graphDB = new GraphDatabaseFactory().
newEmbeddedDatabaseBuilder( graphDBName ).
setConfig( GraphDatabaseSettings.node_keys_indexable, "emailID" ).
setConfig( GraphDatabaseSettings.node_auto_indexing, "true" ).
setConfig( GraphDatabaseSettings.dump_configuration, "true").
newGraphDatabase();
Neo4jGraph g = new Neo4jGraph(graphDB);
if (populateDB) {
println "Populating graph"
g.loadGraphML(databaseName);
}
return g;
}
and my retrieval was done like this:
ReadableIndex<Node> autoNodeIndex = graph.rawGraph.index()
.getNodeAutoIndexer()
.getAutoIndex();
def node = autoNodeIndex.get( "emailID", "<2614099.1075839927264.JavaMail.evans#thyme>" ).getSingle();
And this seemed to work. Note, however, that the getIndices() call on the Neo4jGraph object still returned an empty list. So the upshot is that I can exercise the Neo4j API correctly, but the Gremlin wrapper seems to be unable to reflect the indexing state. The expression g.idx('node_auto_index') (documented in Gremlin Methods) returns null.
the auto indexes are created lazily. That is - when you have enabled the auto-indexing, the actual index is first created when you index your first property. Make sure you are inserting data before checking the existence of the index, otherwise it might not show up.
For some auto-indexing code (using programmatic configuration), see e.g. https://github.com/neo4j-contrib/rabbithole/blob/master/src/test/java/org/neo4j/community/console/IndexTest.java (this is working with Neo4j 1.8
/peter
Have you tried the automatic index feature? It's basically the use case you're looking for--unfortunately it needs to be enabled before you import the data. (Otherwise you have to remove/add the properties to reindex them.)
http://docs.neo4j.org/chunked/milestone/auto-indexing.html

Can Doctrine_RawSql be used with sfDoctrinePager?

I have a complex query that needs to be performed on given relationships (INNER JOINS) that are not defined in the Symfony schema. The query itself already takes quite some time, so I've opted to exclude it from the Doctrine schema and elected to use raw queries isntead. However, I would still like to to use the Doctrine pagination within the Symfony framework. Is this possible?
Yes it is.
After you create the query with Doctrine_RawSql you just have to add it to the pager. For example:
$query = new Doctrine_RawSql();
$query->addComponent('a', 'Class')->where('a.id = ?', 1);
$pager = new sfDoctrinePager('Class', 25);
$pager->setQuery($query);
$pager->init();

Resources