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

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;

Related

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

how to select value if key is uuid in mongodb

the mongodb data like this:
{
"_id": "123dsadasfa454sdsaw",
"hashmap": {
"uuid-12sadsadw5": {
"name": "bob"
},
"uuid-12sadsadwew5": {
"name": "alice"
}
},
"age": 10
}
"hashmap" like java HashMap, the key is uuid like "uuid-12sadsadwew5" and the value is object.
I want to get the data which the name in "hashmap" value is not null. And I use sql :
db.tabl1.find({"hashmap.values.name":{$ne:null}})
but cannot get the right result
You can use this aggregation query:
First use $objectToArray to create an array with values k and v. As we don't know the key (k) we can search by value (v).
Then $unwind array
And $match values where name is not null.
And then regroup and recreate the object using $arrayToObject.
db.collection.aggregate([
{
"$set": {
"hashmap": {
"$objectToArray": "$hashmap"
}
}
},
{
"$unwind": "$hashmap"
},
{
"$match": {
"hashmap.v.name": {
"$ne": null
}
}
},
{
"$group": {
"_id": "$_id",
"hashmap": {
"$push": "$hashmap"
}
}
},
{
"$set": {
"hashmap": {
"$arrayToObject": "$hashmap"
}
}
}
])
Example here

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)

React Native -- Loop through array of objects to return value

Data:
{
"contextTag": {
"value": "Bittersweet",
"valueLabel": "Bittersweet"
},
"tags": [
{
"name": "tag",
"value": "Creamy"
},
{
"name": "tag",
"value": "Colorful"
},
{
"name": "tag",
"value": "Bright"
}
],
"rating": 5,
"userNickName": "HelloGames",
"userLocation": "UK",
"title": "Great!",
"reviewText": "Yada yada yada yada",
"submissionTime": "30 Nov 16"
},
I currently have this working for getting contextTag valueLabels:
this.props.reviewData.reviews.map(
(o) => {
return o.contextTag && o.contextTag.valueLabel ? o.contextTag.valueLabel.trim() : '';
}
)
And this for tags:
this.props.reviewData.reviews.map(
(o) => {
return o.tags && o.tags.value ? o.tags.value.trim() : '';
}
)
But it's coming back empty. How do I loop through tags to grab each of the values?
You can cache the tags, then map over it to get the values. Like below:
const tags = this.props.reviewData.reviews.tags;
const tags_values = ( tags ? tags.map((tag) => (tag.value ? tag.value : '' ) : []); // this an array of the tags values.
Your code does not return what you want because the tags attributes is an array of objects, so to get the tag values you have to map over it as I did above.
Hope this helped.

Nest serialize elasticsearch Terms Query request

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"))))));