Nest serialize elasticsearch Terms Query request - nest

I'm using NEST 2.0.2 to query ElasticSearch.
Really great API, thanks for the effort, but needs documentation update I think.
Anyways,
I want to serialize my request. I could not find any info, there are some stackoverflow questions but it's about older versions, and api changed.
I want to write a "terms query". But could not succeed.
The working sense DSL is below.
GET myindex/mytype/_search?search_type=count
{
"query": {
"bool": {
"must": [
{
"term": {
"field1": {
"value": 2
}
}
}
],
"must_not": [
{
"terms": {
"field2": [
16,
17,
18,
19
]
}
}
]
}
},
"aggs": {
"termsAggField2": {
"terms": {
"field": "field2",
"size": 20
},
"aggs": {
"sumAggField3": {
"sum": {
"field": "field3"
}
}
}
}
}
}
And the terms query code is below. DSL works in sense, but the query does not working. The "not in" does not filter the output.
List<QueryContainer> must_not = new List<QueryContainer>();
must_not.Add(Query<mytype>.Terms(trms => trms.Terms(new string[] { "16", "17", "18", "19" })));
var resultTermsSum = b1.ElasticClient.Search<mytype>(q=>q.SearchType(SearchType.Count)
.Query(q2 => q2.Bool(
b => b.MustNot(must_not.ToArray())
)
)
.Aggregations(a => a.Terms("termsAggField2", terms => terms.Field("field2").Size(20)
.Aggregations(a2 => a2.Sum("sumAggField3", sum => sum.Field("field3"))))));
ie why I want to see the serialized request and see my problem.
thanks.
regards.
Edit: It's now working with the following update. It'd be great if I could serialize ;)
List<QueryContainer> must_not = new List<QueryContainer>();
short [] valueCollection = new short[] { 16, 19, 99, 100 };
must_not.Add(Query<mytpe>.Terms(trms => trms.Field("field2").Terms(valueCollection)));
var resultTermsSum = b1.ElasticClient.Search<mytype>(q=>q.SearchType(SearchType.Count)
.Query(q2 => q2.Bool(
b => b.MustNot(must_not.ToArray())
)
)
.Aggregations(a => a.Terms("termsAggField2", terms => terms.Field("field2").Size(20)
.Aggregations(a2 => a2.Sum("sumAggField3", sum => sum.Field("field3"))))));

Related

"INVALID_CURSOR_ARGUMENTS" from Github graphql API

I am using the following query:
query myOrgRepos {
organization(login: "COMPANY_NAME") {
repositories(first: 100) {
edges {
node {
name
defaultBranchRef {
target {
... on Commit {
history(after: "2021-01-01T23:59:00Z", before: "2023-02-06T23:59:00Z", author: { emails: "USER_EMAIL" }) {
edges {
node {
oid
}
}
}
}
}
}
}
}
}
}
}
But with accurate names for the orginization and emails, and am persistantly getting the following error for every repo.
{
"type": "INVALID_CURSOR_ARGUMENTS",
"path": [
"organization",
"repositories",
"edges",
20,
"node",
"defaultBranchRef",
"target",
"history"
],
"locations": [
{
"line": 10,
"column": 29
}
],
"message": "`2021-01-01T23:59:00Z` does not appear to be a valid cursor."
},
If I remove the after field, it works just fine. However, I kind of need it. Acording to all the docs that I have read both after and before take the same timestamp. Can't tell where I am going wrong here.
I have tried:
to narrow the gap between before and after
return only a single repository
remove after (works fine without it)

GraphQL pagination partial response with error array

I have a query like below
query {
heroes {
node {
name
}
endCursor
}
}
I am trying to understand how GraphQL can handle the error handling and return partial response. I looked at https://github.com/graphql/dataloader/issues/169 and tried to create a resolver like below;
{
Query: {
heroes: async (_) => {
const heroesData = await loadHeroesFromDataWarehouse();
return {
endCursor: heroesData.endCursor;
node: heroesData.map(h => h.name === 'hulk' ? new ApolloError('Hulk is too powerful') : h)
}
}
}
}
I was hoping it would resolve something like below;
{
"errors": [
{
"message": "Hulk is too powerful",
"path": [
"heroes", "1"
],
}
],
"data": {
"heroes": [
{
"name": "spiderman"
},
null,
{
"name": "ironman"
}
]
}
}
but it is completely failing making the heroes itself null like below;
{
"errors": [
{
"message": "Hulk is too powerful",
"path": [
"heroes"
],
}
],
"data": {
"heroes": null
}
}
How can I make resolver to return me the desired partial response?
Found the solution, basically we need a resolver to resolve the edge model itself;
{
Query: {
heroes: (_) => loadHeroesFromDataWarehouse()
},
HeroesEdge {
node: async (hero) => hero.name === 'hulk' ? new ApolloError('Hulk is too powerful') : hero
}
}

knex json array of object where condition

I have a json array (composition) in my db and i need to make conditions
[
{
"name": "Rock",
"prices": [
{
"price": 400,
"duration": 40
}
],
"description": "Hello",
"nb_musicians": 40
}
]
And i try something like this but dont work
.where(qb => {
if (nbMusicians) {
qb.whereRaw(
`composition->
'$.nb_musicians' = ?`,
[40],
);
}
})
Thanks for help

Karate - filter a specific json key from response based on another static array

I have the following JSON response (reference name: "list") and
[
{
"key": "101",
"val": {
"portCall": {
"id": 12664978
},
"status": "in-port"
}
},
{
"key": "102",
"val": {
"portCall": {
"id": 12415798
},
"status": "in-port"
}
},
{
"key": "103",
"val": {
"status": "on-voyage",
"voyage": {
"id": "7kynv-7lq85"
}
}
},
{
"key": "104",
"val": {
"status": "on-voyage",
"voyage": {
"id": "7kynv-2385"
}
}
}
]
also, I have an array list of few key values, evImos = [101,102,104]
In that, I have to identify the first key in the "list" response that has status as "on-voyage". So, the result should be "104".
I have tried the following and I need some help to make it work. Any help would be appreciated.
* def function getFirst = function(evImos) { for (let num of evImos) { let results = list.filter(d => d["key"] === num && d["val"]["status"] === "on-voyage"); if(results.length === 1) { karate.log(num); return num; } } }
* list.forEach(getFirst(evImos))
I'll just give you one hint. This one line will convert the whole thing in to a form that is much easier for you to validate:
* def temp = {}
* list.forEach(x => temp[x.key] = x.val.status)
Which gives you:
{
"101": "in-port",
"102": "in-port",
"103": "on-voyage",
"104": "on-voyage"
}
Now you can do:
* def isOnVoyage = function(key){ return temp[key] == 'on-voyage' }
Also read this: https://stackoverflow.com/a/59162760/143475
Thanks, to #Peter.
Based on his hint, I just tweaked it a little bit to match my requirement and it worked for me.
Here is the working copy for anyone to refer in the future.
* def temp = {}
* list.forEach(x => temp[x.key] = x.val.status)
* def isOnVoyage = function(keys){ for (let key of keys) { if(temp[key] == 'on-voyage'){ karate.log(key); karate.set('num', key); break; }}}
* isOnVoyage(evImos)

How to pass an object to "Origin" method in NEST (FunctionScore query)?

I am trying to create a function_score elasticsearch query using NEST (gauss function), and have a geo point object to pass as the 'origin', however the "Origin" method in NEST accepts only a string, a result elasticsearch can't parse the query.
How can I write the query in NEST so Elasticsearch can parse it correctly?
var originLoc = JsonConvert.SerializeObject(userLocation.GeoCenter);
var searchDesc = new SearchDescriptor<MyCustomType>().Query(q => q.FunctionScore(fs => fs.Functions(func => func.Gauss("geoCenter", gs => gs.Origin(originLoc).Offset("1km").Scale("500m").Decay(0.99)))));
NEST passes the code above to elasticsearch like this, which elasticsearch can't parse (origin is parsed as string).
"query": {
"function_score": {
"functions": [
{
"gauss": {
"geoCenter": {
"origin": "{\"lat\":29.745703,\"lon\":-95.740514}", //<-- string
"scale": "500m",
"offset": "1km",
"decay": 0.99
}
}
}
]
}
}
Below is the correct query that Elasticsearch can run (origin is parsed as geo point object)
"query": {
"function_score": {
"functions": [
{
"gauss": {
"geoCenter": {
"origin": { //<----- geo point serialized object
"lon": -95.740514,
"lat": 29.745703
},
"scale": "500m",
"offset": "1km",
"decay": 0.99
}
}
}
]
}
i have something like this in my code
.Query(f => f
.FunctionScore(fs => fs
.BoostMode(FunctionBoostMode.Sum)
.Functions(ff => ff
.Linear("location", d => d.Origin(origin).Scale("8km").Decay(0.33))
)
)
)
Where origin -> var origin = object.latitude + "," + object.longitude;