I want filter result from Elasticsearch where array of strings contain one of specific string value:
This is current json result, no filtered :
{
"id": 1,
"title": "Title",
"tags": [
"tag filter"
],
},
{
"id": 2,
"title": "Title",
"tags": [
"different tag filter"
],
},
Objectif : obtain only result where tags contain simple "tag filter"
What i made:
$termsQuery = new Terms('POITypes');
$termsQuery->setTerms($terms); // $terms => array("tag filter")
$boolQuery->addMust($termsQuery);
What dd report:
SearchController.php on line 90:
Elastica\Query\BoolQuery {#892
#_params: array:1 [
"must" => array:1 [
0 => Elastica\Query\Terms {#893
#_params: array:1 [
"tags" => array:1 [
0 => "tag filter"
]
]
#_rawParams: []
-field: "tags"
}
]
]
#_rawParams: []
}
When i add this must filter with this terms requirement, there are 0 result obtain. I found no solution since 2 days for this simple query... what's wrong with my code ?
Expecting only result where tags array includes one of my terms values.
Pass field name as tags.keyword.
Tags field is of type "text" so your query is trying to match "tag filter"against individual tokens["tag","filter"], you need to match it against full value.
If index was auto created , it will have keyword subfield by default, otherwise you will need to create it.
Related
I have a schema called posts with a field called categories, a reference type in Sanity.
{
name: 'categories',
title: 'Categories',
type: 'array',
of: [{type: 'reference', to: {type: 'category'}}],
},
I need to get that title from the categories. When I get all posts, that field is coming as an object like:
[
{
"_key": "1cac01eebf24",
"_ref": "507759ee-9e76-4466-8e57-eec7686fb25c",
"_type": "reference"
}
]
Is there a way to get the reference data corresponding to that post?
Thank you.
I have a JSON object(Form) in the mongo collection like this
{
"_id": "87124eb6-c9f7-49b9-8470-8c2b7fb07dc8",
"VisitName": "demo visit",
"Version": "string",
"FormStatus": "string",
"FormName": "demo form",
"IsDeleted": false,
"Pages": [
{
"PageName": "demo page",
"PageNo": 1,
"PageStatus": true,
"Field": [
{
"FieldName": "Gender",
"Value": "demo value",
"Comment": "demo comment",
}
]
}
]
}
I need to edit the Field (which is an array of objects ).
Currently, I am loading the full form and replacing the field data to be updated, Then replace the new form with the old one.
loading the whole form for each field update may affect performance, when loading large forms
Is there any way to update only the field details with fieldName(Unique) Instead of fetching the whole Form and editing?
Update: I missed the ASP.NET tag before answering this. I hope, this still gets you to the solution
You can use an update with arrayFilters. Here's a playground link to test it.
db.collection.update({
"FormName": "demo form"
},
{
$set: {
"Pages.$[pageItem].Field.$[fieldItem].Value": "new value"
}
},
{
arrayFilters: [
{
"pageItem.PageName": "demo page"
},
{
"fieldItem.FieldName": "Gender"
}
]
})
Basically, you tell MongoDB, update the nested field in the corresponding array element, that fulfils the filter specified by arrayFilters. So in this case, you update the path: "Pages.$[pageItem].Field.$[fieldItem].Value" to the new value but only in those nested documents, that:
reside in a page, whose name is demo page
and, in that page, there is a filed, whose name is Gender
I have this relationship:
person --likes--> subject
This is my query:
g.V().
hasLabel('person').
has('name', 'Joe').
outE('likes').
range(0, 2).
union(identity(), inV().hasLabel('subject')).
valueMap('rating', 'name').
At this point, I get result that looks like this:
[
{
"rating": 3.236155563
},
{
"rating": 3.162886797
},
{
"name": "math"
},
{
"name": "history"
}
]
I'd like to get something like this:
[
{
"rating": 3.236155563,
"name": "math"
},
{
"rating": 3.162886797,
"name": "history"
},
]
I've tried grouping the results - which gives me the structure I want - but because of the identical keys, I only get 1 set of results back.
It always helps when you post the code to create the graph so we can give you a tested answer. Like so
g.addV('person').property('name', 'P1').as('p1').
addV('subject').property('name', 'Math').as('math').
addV('subject').property('name', 'History').as('history').
addV('subject').property('name', 'Geography').as('geography').
addE('likes').from('p1').to('math').property('rating', 1.2).
addE('likes').from('p1').to('history').property('rating', 2.3).
addE('likes').from('p1').to('geography').property('rating', 3.4)
I believe you are trying to write a traversal that starts from a certain person, go out along the first two "likes" edges and get the names of the subjects that he likes and the rating on the corresponding "likes" edge.
g.V().has('person', 'name', 'P1').
outE('likes').
range(0, 2).
project('SubjectName', 'Rating').
by(inV().values('name')).
by(values('rating'))
The following is my structure of data
[
{
"id": 1,
"title": "Welcome to my playground",
"description": "This is so fun to play with, you will like it <3",
"comments": [
{
"id": 1140406,
"comment": "this is an example comment",
"postId": 1
}
]
},
...
]
And I'm trying to use immutable js to do this operation
Get all the posts
Search for a post I want to add comment to
Adding the comments when the post is found
The following is my code
posts = posts.map((post) => {
if(post.get('id') == payload.post_id) {
return post.update('comments', (comments) => {
return comments.push(Map({
id: payload.id,
comment: payload.comment
}));
});
}
return post;
});
But I assume this pattern is very common and there should be a simpler way to do this in immutableJS. Any advice will be helpful, thanks.
First off, it's worth mentioning that your Data structure is Immutable Lists and Maps.. not JS Arrays and Objects.
OK, without changing your data structure you could do:
posts.map(post => post.get('id') === payload.post_id ?
post.update('comments', comments.push(payload) :
post)
If you were to change your data structure, and instead of having a List of posts, had a Map of post's with their ID as the key you could just do:
post.updateIn([payload.post_id, 'comments'], comments => comments.push(payload))
BTW you can use push or concat here, both will function the same.
Also, if comments may be undefined, you can provide a "noSetValue" as a List (https://facebook.github.io/immutable-js/docs/#/List/updateIn):
posts.map(post => post.get('id') === payload.post_id ?
post.update('comments', Immutable.List([]), comments.push(payload) :
post)
post.updateIn([payload.post_id, 'comments'], Immutable.List([]), comments => comments.push(payload))
For others who has the same question: One should consider a data normalisation (search for normalizr). You could then normalise your data to something like:
"entities": {
"posts": {
"1": {
"id": 1,
"title": "Welcome to my playground",
"description": "This is so fun to play with, you will like it <3",
"comments": [1140406, 1140407, 1140408]
},
"42" : {...}
}
"comments": {
"1140406": {
"id": 1140406,
"comment": "this is an example comment",
"postId": 1
},
"1140407": {...}
}
}
then updating post and comments becomes much easier
i want to sort my result of companies based on the count of nested (employment)objects,
i added an extra field to the company entity that holds the count like:
private employeeCount;
getEmployeeCount(){
return count($this->employments);
}
and added it to the index like:
company:
mappings:
fullname: ~
employeeCount: ~
the field is correctly indexed and i get hits like:
"_hit": {
"_index": "search",
"_type": "company",
"_id": "2628",
"_source": {
"fullname": "acme",
"employeeCount": 9,
... },
"sort": [
"9"
]
i added the sort like:
$query->addSort(array('employeeCount' => array( 'order'=>'desc')));
and the result seems to be sorted correctly down from " 9, 8, 7, 6 ...",
but for some reason there are some results somewhere in the middle with higher employeeCount
for example this:
"_hit": {
"_index": "search",
"_type": "company",
"_id": "2668",
"_source": {
"fullname": "acme2",
"employeeCount": 18,
... },
"sort": [
"18"
]
i expect this result to be on top of my first example but it is somewhere between 2 and 1
so two guesses, it is sorting from 0-10 and everything greater than 10 is ignored
or there is some bug in elasticsearch or foselastica bundle,
heres the resulting query:
search/company/_search (GET) 5.59 ms {"sort":[{"employeeCount":{"order":"desc"}}],"query":{"wildcard":{"fullname":{"value":"**","boost":1}}},"size":"2000","from":0}
anybody any idea ?
Seems like it is sorting as a string instead of an integer. You can add a type to the sort params to specify integer.