RethinkDB subquery sample error - rethinkdb

Sample on http://www.rethinkdb.com/docs/table-joins/, titled "Using subqueries" does not work as expected. Apart from the typo on the word lambda can you suggest the fix ?

The example posted in http://www.rethinkdb.com/docs/table-joins/ is a Python example. If you want to try out the example in Ruby, try the entering the following query into irb:
r.table("companies").get(id).merge{ |company| {
:employees => r.table('employees')
.get_all(company['id'], :index => 'company_id')
.coerce_to('array') }
}.run(Conn)
The result of that query should look something like this:
irb(main):254:0> r.table("companies").get(id).merge{ |company| {
irb(main):255:2* :employees => r.table('employees')
irb(main):256:2> .get_all(company['id'], :index => 'company_id')
irb(main):257:2> .coerce_to('array') }
irb(main):258:1> }.run(Conn)
=> {"company"=>"Starfleet", "company_id"=>"064058b6-cea9-4117-b92d-c911027a725a", "employees"=>[], "id"=>"064058b6-cea9-4117-b92d-c911027a725a", "name"=>"Jean-Luc Picard", "rank"=>"captain", "type"=>"paramilitary"}
Make sure that all the appropriate tables and indexes have been created before you run the query:
// Create the tables
r.table_create("companies").run(Conn)
r.table_create("employees").run(Conn)
// Create the index
r.table("employees").index_create("company_id").run(Conn)
// Insert a document
r.table("companies").insert({
"id": "064058b6-cea9-4117-b92d-c911027a725a",
"name": "Jean-Luc Picard",
"company_id": "064058b6-cea9-4117-b92d-c911027a725a",
"rank": "captain",
"company": "Starfleet",
"type": "paramilitary"
}).run(Conn)

Related

Trying to filter some Elasticsearch results where the field might not exist

I have some data and I'm trying to add an extra filter that will exclude/filter-out any results which is where the key/value is foo.IsMarried == true.
Now, there's heaps of documents that don't have this field. If the field doesn't exist, then I'm assuming that the value is foo.IsMarried = false .. so those documents will be included in the result set.
Can anyone provide any clues, please?
I'm also using the .NET 'NEST' nuget client library - so I'll be really appreciative if the answer could be targeting that, but just happy with any answer, really.
Generally, within elasticsearch, for a boolean field, if the field doesn't exist, it doesn't mean that it's value is false. It could be that there is no value against it.
But, based on the assumption you are making in this case - we can check if the field foo.isMarried is explicitly false OR it does not exist in the document itself.
The query presented by Rahul in the other answer does the job. However since you wanted a NEST version of the same, the query can be constructed using the below snippet of code.
// Notice the use of not exists here. If you do not want to check for the 'false' value,
// you can omit the first term filter here. 'T' is the type to which you are mapping your index.
// You should pass the field based on the structure of 'T'.
private static QueryContainer BuildNotExistsQuery()
{
var boolQuery = new QueryContainerDescriptor<T>().Bool(
b => b.Should(
s => s.Term(t => t.Field(f => f.foo.IsMarried).Value(false)),
s => !s.Exists(ne => ne.Field(f => f.foo.IsMarried))
)
);
}
You can trigger the search through the NEST client within your project as shown below.
var result = client.Search<T>(
.From(0)
.Size(20)
.Query(q => BuildNotExistsQuery())
// other methods that you want to chain go here
)
You can use a should query with following conditions.
IsMarried = false
must not exists IsMarried
POST test/person/
{"name": "p1", "IsMarried": false}
POST test/person/
{"name": "p2", "IsMarried": true}
POST test/person/
{"name": "p3"}
Raw DSL query
POST test/person/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"IsMarried": false
}
},
{
"bool": {
"must_not": {
"exists": {
"field": "IsMarried"
}
}
}
}
]
}
}
}
I hope you can convert this raw DSL query to NEST!

Logstash/Elasticsearch JDBC document_id vs document_type?

So im trying to wrap my head around the document_type vs document_id when using the JDBC importer from logstash and exporting to elasticsearch.
I finally wrapped my head around indexes. But lets pretend im pulling from a table of sensor data (like temp/humidity/etc...) that has sensor id's...temps/ humidity (weather related data) with time recorded. (So it's a big table)
And I want to keep polling the database every X so often.
What would document_type vs document_id be in this instance, this is going to be stored (or whatever you want to call it) against 1 index.
The document_type vs document_id confuses me, especially in regards to JDBC importer.
If I set document_id to say my primary key, won't it get over-written each time? So i'll just have 1 document of data each time? (which seems pointless)
The jdbc plugin will create a JSON document with one field for each column. So to keep consistent with your example, if you had that data it would be imported as a document that looks like this:
{
"sensor_id": 567,
"temp": 90,
"humidity": 6,
"timestamp": "{time}",
"#timestamp": "{time}" // auto-created field, the time Logstash received the document
}
You were right when you said that if you set document_id to your primary key, it would get overwritten. You can disregard document_id unless you want to update existing documents in Elasticsearch, which I don't imagine you would want to do with this type of data. Let Elasticsearch generate the document id for you.
Now let's talk about document_type. If you want to set the document type, you need to set the type field in Logstash to some value (which will propagate into Elasticsearch). So the type field in Elasticsearch is used to group similar documents. If all of the documents in your table that you're importing with the jdbc plugin are of the same type (they should be!), you can set type in the jdbc input like this...
input {
jdbc {
jdbc_driver_library => "mysql-connector-java-5.1.36-bin.jar"
jdbc_driver_class => "com.mysql.jdbc.Driver"
jdbc_connection_string => "jdbc:mysql://localhost:3306/mydb"
jdbc_user => "mysql"
parameters => { "favorite_artist" => "Beethoven" }
schedule => "* * * * *"
statement => "SELECT * from songs where artist = :favorite_artist"
...
type => "weather"
}
}
Now, in Elasticsearch you can take advantage of the type field by setting a mapping for that type. For example you might want:
PUT my_index
{
"mappings": {
"weather": {
"_all": { "enabled": false },
"properties": {
"sensor_id": { "type": "integer" },
"temp": { "type": "integer" },
"humidity": { "type": "integer" },
"timestamp": { "type": "date" }
}
}
}
}
Hope this helps! :)

Extracting matching conditions from querystring

ElasticSearch Query is formed using query string with multiple AND / OR operators. i.e. ((Condition 1 OR Condition 2) AND (Condition 3 OR Condition 4 OR Condition 5)), based on the condition it provides me multiple documents. For getting exact condition I again loop through all the resultant documents again and mark particular conditions. Is there any simple way to get resultant conditions specific to documents ?
Can anyone provide the better example using NEST API?
I think that what you need is to Highlight the data that made the hit on your query. Highlight functionality of elasticsearch actually marks the text from each search result so the user can see why the document matched the query. The marked text is returned in the response.
Please refer in the elasticsearch documentation in order to understand how this api actually works. Refer in the Nest Documentation in order to see how you can implement it with the Nest library.
For example, using the elasticsearch api imagine the below example:
GET /someIndex/someType/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
},
"highlight": {
"fields" : {
"about" : {}
}
}
}
The same with Nest:
var result = _client.Search<someIndex>(s => s
.Query(q => q
.MatchPhrase(qs => qs
.OnField(e => e.about)
.Query("rock climbing")
)
)
.Highlight(h => h
.OnFields(f => f
.OnField(e => e.about)
)
)
);
The response will be of the below form for each search result (notice the highlight part)
"_score": 0.23013961,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [ "sports", "music" ]
},
"highlight": {
"about": [
"I love to go <em>rock</em> <em>climbing</em>"
]
}

Searching for a document in MongoDB by value of it's array - Mongoid/Sinatra

I got document in Mongo
{
"_id": ObjectId("53638084e1054e706f000001"),
"name": "Vasya",
"order": [
"burger",
"nuggets",
"mtdew"
],
}
Now I need to find it
get '/order/:order' do
#clients = Client.where(order: [':order'])
haml :index
end
But it returns nothing. Please help me with this action.
If you just want to find documents with a specific element in the order array:
db.orders.find({"order": "nuggets"})
In Ruby syntax it should be (untested):
get '/order/:order' do
#clients = Client.where(order: params[:order])
haml :index
end

Find matching array items in MongoDB document

I am developing a web app using Codeigniter and MongoDB.
In the database I got a document that look like this:
{
"_id": {
"$id": "4f609932615a935c18r000000"
},
"basic": {
"name": "The project"
},
"members": [
{
"user_name": "john",
"role": "user",
"created_at": {
"sec": 1331730738,
"usec": 810000
}
},
{
"user_name": "markus",
"role": "user",
"created_at": {
"sec": 1331730738,
"usec": 810000
}
}
]
}
I need to search this document using both user_name and role. Right now when I am using the below code I get both. I only want to get array items matching both user_name and role.
$where = array (
'_id' => new MongoId ($account_id),
'members.user_id' => new MongoId ($user_id),
'members.role' => $role
);
$this -> cimongo -> where ($where) -> count_all_results ('accounts');
This is an old question, but as of MongoDB 2.2 or so you can use the $ positional operator in a projection so that only the matched array element is included in the result.
So you can do something like this:
$this->cimongo->where($where)->select(array('members.$'))->get('accounts');
This is a repeat of this question:
Get particular element from mongoDB array
Also you might want to use $elemMatch
http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArray
Here is the rub -- you aren't going to be able to get the array items that match because mongo is going to return the entire document if those elements match. You will have to parse out the code client side. Mongo doesn't have a way to answer, "return only the array that matches."

Resources