Nest - how to do a SpanFirstQuery? - elasticsearch

I am trying to do a SpanFirstQuery with NEST, as described in:
https://www.elastic.co/guide/en/elasticsearch/reference/1.4/query-dsl-span-first-query.html
The SpanFirstQuery class has a Match property, but the Match property is an ISpanQuery which has a SpanFirst property that is a ISpanFirstQuery. That seems to be an endless loop.
I am confused..
How to do a spanfirstquery with NEST?
Thanks.

A span_first query in NEST can be done very simply like this:
var s = new SearchDescriptor<ElasticsearchProject>()
.Query(q => q
.SpanFirst(sf=>sf
.MatchTerm(f => f.User, "kimchy")
.End(3)
)
);
That will produce the same query as depicted in the official documentation:
{
"span_first" : {
"match" : {
"span_term" : { "user" : "kimchy" }
},
"end" : 3
}
}

Related

Elastic search nest search query

I am getting stuck getting while implementing search using elastic search nest.
I have to implement like query with elastic search.
for ex. select * from table where username like '%abc xyz%'
As you can see in above sql query I have applied like query with string "abc" space and another string "xyz". Similarly I want this query in elastic search. Can anyone help me to implement such query in elastic search nest?
Below is the query
Client.Search<Video>(s => s
.Query(q => q
.Match(m => m
.OnField("video_parent")
.Query("0")
) && q
.Match(m => m
.OnField("video_status")
.Query(objVideosFilterCriteria.Vide‌​oStatus.ToString())
) && q
.MatchPhrase(ff=>ff
.OnField("video_title")
.Query(objVideosF‌​ilterCriteria.Search‌​String)
) && q
.Range(r => r
.OnField(f => f.video_date)
.GreaterOrEquals(fromDate)
.LowerOrEquals(toDate‌​)
)
)
.From(objVideosFilterCriteria.PageIndex)
.Size(objVideosFilt‌​erCriteria.PageSize)
‌​);
Above is the query I am using. In this query I am using
q.MatchPhrase(ff=>ff
.OnField("video_title")
.Query(objVideosF‌​‌​ilterCriteria.Sear‌​ch‌​String)
)
for like query. But it doesn't seem to work.
I am using below data set and want to filter data from below list.
"hits" : [
{
"_source" : {
"video_id" : 265006,
"video_title" : "nunchuk rockin roller II"
}
},
{
"_source" : {
"video_id" : 265013,
"video_title" : "?Shaggy?????Locks???7??????Alberto E. Interview {407} 967 ~ 8596?"
}
},
{
"_source" : {
"video_id" : 265014,
"video_title" : "Shakin' Stevens - Kalundborg Rocker"
}
},
{
"_source" : {
"video_id" : 265019,
"video_title" : "?Shaggy?????Locks? = 7??????Greg M. Interview {407} 967 ~ 8596?"
}
},
{
"_source" : {
"video_id" : 265023,
"video_title" : "?Shaggy?????Locks? = 7??????Jason M. Interview {407} 967 ~ 8596?"
}
}
]
For example I would like to search with the keyword "kin rol" in the "video_title" field so with the above data it should fetch one record which exists at first position in above list but in my current query I am getting. nothing.

Springdata mongodb aggregation match

After asking question to understand a bit more of the aggregation framework in MongoDB I finally found the way to do aggregation for my need (thanks to a StackExchange user)
So basically here is a document from my collection:
{
"_id" : ObjectId("s4dcsd5s4d6c54s6d"),
"items" : [
{
type : "TYPE_1",
text : "blablabla"
},
{
type : "TYPE_2",
text : "blablabla"
},
{
type : "TYPE_3",
text : "blablabla"
},
{
type : "TYPE_1",
text : "blablabla"
},
{
type : "TYPE_2",
text : "blablabla"
},
{
type : "TYPE_1",
text : "blablabla"
}
]
}
The idea was to be able to filter only some elements of my collections (avoiding Type 2 and 3). In fact I have more than 30 types and 6 are not allowed but for simplicity I made this example.
So the aggregation command in command line is this one:
db.history.aggregate([{
$match: {
_id: ObjectId("s4dcsd5s4d6c54s6d")
}
}, {
$unwind: '$items'
}, {
$match: {
'items.type': { '$nin': [ "TYPE_2" , "TYPE_3"] }
}
},
{ $limit: 10 }
]);
With this I am able to retrieve the 10 elements items of this document which do not match TYPE_2 and TYPE_3
However when I am using spring data there is no output. I looked a bit at the example to build mine but its still not working.
So I did:
Aggregation aggregation = newAggregation(
match(Criteria.where("id").is(myID)),
unwind("items"),
match(Criteria.where("items.type").nin(ignoreditemstype)),
limit(3),
skip(offsetLong)
);
AggregationResults<PersonnalHistory> results = mongAccess.getOperation().aggregate(query,
"items", PersonnalHistory.class);
PersonnalHistory is marked with annotation #Document(collection = "history") and id with the #id annotation
ignoreditemstype is a list containing TYPE_2 and TYPE_3
Here is what I have in the toString method of aggregation:
{
"aggregate" : "__collection__" ,
"pipeline" : [
{ "$match": { "id" : "s4dcsd5s4d6c54s6d"} },
{ "$unwind": "$items"},
{ "$match": { "items.type": { "$nin" : [ "TYPE_2" , "TYPE_3" ] } } },
{ "$limit" : 3},
{ "$skip" : 0 }
]
}
I tried a lot of stuff (to have at least an answer :) ) like removing id or the nin:
aggregation = newAggregation(
unwind("items"),
match(Criteria.where("items.type").nin(ignoreditemstype)),
limit(3),
skip(offsetLong)
);
aggregation = newAggregation(
match(Criteria.where("id").is(myid)),
unwind("items")
);
For information when I do a simple query like:
query.addCriteria(Criteria.where("id").is(myID));
My document is returned. However I have thousands of items. So I just want to have the 15 first (in fact the 15 first are the 15 last added)
Do you maybe see what I am doing wrong?
Yeah looks like you are passing simple String while it is expecting ObjectId
Aggregation aggregation = newAggregation(
match(Criteria.where("_id").is(new ObjectId(myID))),
unwind("items"),
match(Criteria.where("items.type").nin(ignoreditemstype)),
limit(3),
skip(offsetLong)
);
Now the question is why it works with simple query, my answer would be because spring-data driver is not that mature at least not with aggregation pipeline.

Nested filter returns wrong result when Object name is not given to search

Using elastic search, I am trying to get data for nested object
BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
NestedQueryBuilder nestedBuilder = QueryBuilders.nestedQuery("Attributes", boolBuilder);
boolBuilder.must(QueryBuilders.termQuery("Attributes.attributeId", "1001"));
Result comes if the query is like this,
{
"nested" : {
"query" : {
"bool" : {
"must" : [ {
"term" : {
"Attributes.attributeId" : "1001"
}
]
}
},
"path" : "Attributes"
}'
Result not coming if the query is like this,
{
"nested" : {
"query" : {
"bool" : {
"must" : [ {
"term" : {
"attributeId" : "1001"
}
]
}
},
"path" : "Attributes"
}
Can somebody help me.Here i have to get result without using "Attributes.attributeId".ie. using "attributeId" alone data have to come.
This is expected as per the nested query documentation
The query path points to the nested object path, and the query (or
filter) includes the query that will run on the nested docs matching
the direct path, and joining with the root parent docs. Note that any
fields referenced inside the query must use the complete path (fully
qualified).

How to use lucene SpanQuery in ElasticSearch

For my project, I thought of using Span Near Queries of ElasticSearch, with the constraint that is, certain tokens may have to searched with Fuzziness. I was able to generate a set of SpanQuery (org.apache.lucene.search.spans.SpanQuery) objects some with fuzzy enabled, some without. I couldn't figure out how to use these set of SpanQueries in ElasticSearch spanNearQuery.
Can someone help me out with right pointers to samples or docs. And is there any way to construct ES SpanNearQueryBuilder with some clauses fuzzy enabled ?
You can wrap an fuzzy query into a span query with Span Multi Term Query:
{
"span_near" : {
"clauses" : [
{ "span_term" : { "field" : "value1" } },
{ "span_multi" :
"match" : {
"prefix" : { "user" : { "field" : "value2" } }
}
}
],
...
}
}

Converting MongoQuery to C# statement

I'm searching for a value in an array of a sub arrays. What will the code in C# look like?
db.File.find({
Properties: {
$elemMatch: {
$elemMatch: {
$in:
['AWS-Uploaded']
}
}
}
});
A simplified version of the documents looks like this:
{
"_id" : ObjectId("4f3b83acec76021c6827769e"),
"Extension" : ".mov",
"Length" : NumberLong(7910975),
"Properties" : [
["MediaId", "20898180"],
["AWS-Uploaded", "11/08/2013 16:15:50"]
]
}
For the query object for returning documents where an array element exists, this should do the job
Query.ElemMatch("Properties",
Query.Exists('AWS-Uploaded',true)
);
To use ElemMatch with query operators, like where MediaId=20898180 would be:
Query.ElemMatch("Properties",
Query.EQ('MediaId',20898180)
);
Hope that helps

Resources