Elastic search search query with Filter - node.js

Am new to elastic search, this is my query to find a exact match in my collection.
{
"query": {
"filtered": {
"query": {
"match": {
"_id": {
"query": "1"
}
}
},
"filter": {
"term" : {
"team_id":"2",
"created_user":"099"
}
}
}
}
}
By running this query I am getting one record, but my problem is its not matching "team_id" filed. When I change team_id to some other value eg: 4, I am still getting the record with team_id = 2, Please help me to write an elastic search query with three fields. Thanks

If you want exact match, be sure that fields that you want to make search operation must be not_analyzed. And it seems you are using multiple case in your filter. You can refactor your query by using and filter like;
{
"query": {
"filtered": {
"query": {
"match": {
"_id": {
"query": "1" // remember that, this will always return one result. Update here according to your needs. For example, use tag instead of _id like tag=responsive in order to get results that matches tag field with responsive
}
}
},
"filter": {
"and": [
{
"term": {"team_id":"2"}
},
{
"term": {"created_user":"099"}
}
]
}
}
}

Related

How to filter data by field that contains specific string in ElasticSearch, Node Js?

I have simple Node Js application.
I want get filtered data by Path field, that contains 'get' word.
For example my data is like below:
"_source": {
"time": "2020-03-12T01:25:41.61836-07:00",
"level": "Info",
"info": {
"IpAddress": "0.0.0.0",
"Path": "/api/test/getTest/1",
"QueryString": "",
"UserAgent": "",
"LogDate": "2020-03-12T08:25:41.6220806Z",
"Username": "cavidan.aliyev",
"NodeId": "123456"
}
In other words my entity object's structure like as below:
{
time,
level,
info: {
IpAddress,
Path,
QueryString,
UserAgent,
LogDate,
Username,
NodeId
}
}
My query is like below:
client.search({
index: collectionName,
body: {
from: (params.currentPage - 1) * params.pageSize,
size: params.pageSize,
"query": {
"bool": {
"must": mustArr,
"filter": [
{
"match_all": {}
}
]
}
}
}
}, function (err, res) {
if (err) {
reject(err);
}
else {
let result = res.hits.hits. map(x => x._source);
resolve(result);
}
});
How I can filter data by Path field, that contains 'get' word?
Please help me, thanks
You can make use of Wildcard Query inside the filter query you have. I'm assuming that you are making use of Standard Analyzer for info.Path field.
Note that for the sake of simplicity I've just mentioned what should be going inside the filter query you have.
If info.Path is nested type:
POST <your_index_name>/_search
{
"query": {
"bool": {
"filter": { <--- Note this
"nested": {
"path": "info",
"query": {
"wildcard": {
"info.Path": {
"value": "*get*"
}
}
}
}
}
}
}
}
If info.Path is object type:
POST <your_index_name>/_search
{
"query": {
"bool": {
"filter": { <--- Note this
"wildcard":{
"info.Path": "*get*"
}
}
}
}
}
Important Note: Wildcard search slows the query performance, and if you have a control on the Elasticsearch's index, then you should definitely look at ngram search model, which creates n-gram tokens at index-time as mentioned in this link.
Let me know if this helps!
If you don't want returned data with "get" keywords, your wildcard should type into the must_not.
For example:
POST <your_index_name>/_search
{
"query": {
"bool": {
"must_not":{
"filter": {
"wildcard":{
"info.Path": "*get*"
}
}
}
}
}
}

Elastic search `filter` query not working

I have been trying to find out entries which match query 'abc' and from all those entries returned by multi_match i need to filter entries based on entries which contain given business_id where business_id is one of the fields.
i have tried with below query but no records returned from search even though there is one record satisfying both must and filter query.
Problem is in filter query as when i commented it got 2 records returned by multi_match as required and now i want to filter these records based on business_id so finally should get only one record but filter query is not working.
GET customer/_search
{
"query": {
"bool": {
"must": {
"dis_max": {
"queries":
{
"multi_match": {
"query": "abc",
"type": "phrase_prefix",
"fields": ["first_name", "last_name", "email", "city", "state", "zip", "country"]
}
}
}
},
"filter": {
"term": {
"business_id": business_id
}
}
}
}
}
Here is how my records in index looks like
In order to debug this, I suggest that you'll only search with the must section in the query and see that you get the result you expect, and then do the same with only the filter part.
What you want to see is that on both queries you'll get the document you expect. I believe that one of them should not return the document you expect, and then you could try to understand why (and update the question if needed).
If both must and filter return the doc you expect then the above query should work just fine. Also, if that doesn't work, please add the document that you expect to receive back
GET customer/_search
{
"query": {
"bool": {
"must": {
"dis_max": {
"queries":
{
"multi_match": {
"query": "abc",
"type": "phrase_prefix",
"fields": ["first_name", "last_name", "email", "city", "state", "zip", "country"]
}
}
}
},
"filter": {
"match": {
"business_id": business_id
}
}
}
}
}
Solution to my Question . Now filter query is working fine as i have replaced term with match.

Elasticsearch exclude empty string when looking in a nested collection

I'm trying to do a seemingly simple elastic query but im failing and i cannot really find anything on the subject.
I have the following model (lets call it response)
{
string id,
int category,
answers: [{
string answer,
string innerId
int type,
}]
}
some of the answers may not have an actual answer (i.e. the answer field is an empty string).
I have 2 scenarios that i have problems with.
My first case i cannot solve is such that I must find all nested objects that are of type = 1 and have something in the answer field. I came up with this query this option which gives me all the responses that have at least one answer that is of type 1, including the responses that have an empty string for answer, which i want to exclude.
{
"query": {
"nested": {
"path": "surveyResponseAnswers",
"query": {
"bool": {
"must": [
{
"match": {
"surveyResponseAnswers.questionType": 1
}
}
]
}
}
}
}
}
Ive tried adding a
"must_not": [{
"match": {
"surveyResponseAnswers.answer": ""
}
]
On the same level as the must but what i think happens is that it gives me the response parent because there are other answers that have a value in the answer property, about which i dont care.
My second case is such that I must find all nested objects that are of type = 1 and the answer field contains another string/substring, for which i came up with the following query, but this gives me results only for answers that match the full search word i have.
{
"query": {
"nested": {
"path": "answers",
"query": {
"bool": {
"must": [{
"match": {
"answers.type": 1
}
}, {
"match": {
"answers.answer": "text"
}
}]
}
}
}
}
}
For you first problem, try using "constant_score" and then filter. Your query will look like this.
{
"query": {
"nested": {
"path": "surveyResponseAnswers",
"query": {
"bool": {
"must": [
{
"match": {
"surveyResponseAnswers.questionType": 1
}
},
{
"constant_score": {
"filter": {
"exists": {
"field": "surveyResponseAnswers.answer"
}
}
}
}
]
}
}
}
}
}
for, your second problem, try using "term", if you want to search for whole word, or "prefix" , based on what you are required.
For more details, please see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html

Getting data from elasticsearch when field is undefined or missing from object

I'm trying to get data from elastic search by querying some field which indicates if the object was already handled. let's call it 'isHandled".
There are some objects that indexed without this field.
Is there any way to get the data that "isHandled" is just not "true" (false or even missing)?
Thanks
You can use the exists query to achieve that. This query will return you all documents where isHandled is either false or not existing.
{
"query": {
"bool": {
"should": [
{
"term": {
"isHandled": "false"
}
},
{
"bool": {
"must_not": {
"exists": {
"field": "isHandled"
}
}
}
}
]
}
}
}

How to query documents where the query should have an and clause?

How do I use the nodejs driver for elastic search do achieve the following scenario. The scenario is that I have to update all documents in a "title" index where the tvSeries id is given and where the tvSeriesNumber is given?
I only want to match documents that fulfill both queries. I know that I should be using the client.updateByQuery method but I'm not sure what to put for the query body.
How about this? You probably need to modify the script in order to update whatever fields you want to.
client.updateByQuery({
index: "title",
type: "type",
body: {
"query": {
"bool": {
"filter": [
{ "term": { "tvSeriesId": 123} },
{ "term": { "tvSeriesNumber": 456} }
]
}
},
"script": {
"inline": "ctx._source.xyz = 'abc'"
}
}
}, function(err, res) {
if (err) {
reportError(err)
}
cb(err, res)
}
)

Resources