Elastic search nest search query - elasticsearch

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.

Related

OrOperator in MongoTemplate not returning values?

I am working on Spring MVC with MongoDB.
I have added criteria for some fields with orOperator, Each Fields has value in database, but List returning is Empty.
criteriaQuery.addCriteria(Criteria.where("First_Name").is(docName.trim())
.orOperator(Criteria.where("Middle_Name").is(docName.trim())
.orOperator(Criteria.where("Last_Name").is(docName.trim()))));
Query printing in console is
Query: { "First_Name" : "ESTHER" , "$or" : [ { "Middle_Name" : "ESTHER" , "$or" : [ { "Last_Name" : "ESTHER"}]}]}, Fields: null, Sort: null
I tried the Like query, but that also results the same
criteriaQuery.addCriteria(Criteria.where("First_Name").regex(docName)
.orOperator(Criteria.where("Middle_Name").regex(docName))
.orOperator(Criteria.where("Last_Name").regex(docName)));
Mongo Query
db.doctor_details.find({ "$or" : {"First_Name" : { "$regex" : "ESTHER"} }, "$or" : [ { "Middle_Name" : { "$regex" : "ESTHER"} , "$or" : [ { "Last_Name" : { "$regex" : "ESTHER"}}]}]})
Help me to get the result, I dont know where my code goes wrong. Help is appreciated!
Thanks
As far as I remember in order to use orOperator you should do:
Query query = new Query(new Criteria().orOperator(criteriaV1,criteriaV2));
it is based on this answer

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.

elastic search filter by documents count in nested document

I have this schema in elastic search.
79[
'ID' : '1233',
Geomtries:[{
'doc1' : 'F1',
'doc2' : 'F2'
},
(optional for some of the documents)
{
'doc2' : 'F1',
'doc3' : 'F2'
}]
]
the Geometries is a nested element.
I want to get all of the documents that have one object inside Geometries.
Tried so far :
"script" : {"script" : "if (Geomtries.size < 2) return true"}
But i get exceptions : no such property GEOMTRIES
If you have the field as type nested in the mapping, the typical doc[fieldkey].values.size() approached does not seem to work. I found the following script to work:
{
"from" : 0,
"size" : <SIZE>,
"query" : {
"filtered" : {
"filter" : {
"script" : {
"script" : "_source.containsKey('Geomtries') && _source['Geomtries'].size() == 1"
}
}
}
}
}
NB: You must use _source instead of doc.
The problem is in the way you access fields in your script, use:
doc['Geometry'].size()
or
_source.Geometry.size()
By the way for performance reasons, I would denormalize and add GeometryNumber field. You can use the transform mapping to compute size at index time.

Nest - how to do a SpanFirstQuery?

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
}
}

How to join 2 match queries into a query for elasticsearch?

I'd like to query for data that user_id is '1' and name is 'John'. It's easy to write a commonly-used SQL:
select * from t where user_id = '1' and name = 'John';
But it's not easy for me to make a query for elasticsearch.
First, I made a query for user_id:
{
"query" : {
"match" : {
"user_id" : "1"
}
}
}
And the results were what I expected.
Then, I made a query for name:
{
"query" : {
"match" : {
"name" : "John"
}
}
}
It worked well, too.
But I couldn't make a query joining 2 conditions with and operation. How can I join those 2 match queries into one using and operation?
What you need is a bool query in which you put all your single queries:
(I could not test the query, it might be wrong, but the bool-query is the answer to your problem)
{
"bool" : {
"must" : [{
"match" : {
"user_id" : "1"
},
"match" : {
"name" : "John"
}
}]
}
}

Resources