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.
Related
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.
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've been looking for a way to override the default sorting of data which is based on primary key.
I found some configuration examples for sorting data from the documentation but it doesn't work.
It says
Unrecognized option "sort" under "easy_admin.list"
easy_admin:
entities:
Customer:
class: AppBundle\Entity\Customer
list:
sort: 'name'
form:
title: 'Add Customer'
form_options: {validation_groups:['Default']}
fields:
- name
- {property: 'gender', type: 'choice', type_options:
{
placeholder: 'Select your gender',
choices: {
Female: 'female',
Male: 'male'
}
} }
- {property: 'birthdate', type: 'date', type_options: {widget: 'single_text'}}
- isActive
new:
form_options: {validation_groups: ['Default','Customer']}
edit:
title: 'Edit Customer'
site_name: 'Premiere Sales'
You use sort option in the wrong place. You should set sort option under your entity scope of configuration:
easy_admin:
entities:
User:
# ...
list:
# if the sort order is not specified, 'DESC' is used
sort: 'createdAt'
It seems that the configuration I posted above is correct and I just restarted the server and the browser and it works fine
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
EDIT: Added my current query to the end
I have a large database of human names and am using elastic search (via symfony2's FOSElasticaBundle and Elastica) to do smarter searching of the names.
I have a full name field, and I want to index the people's names with standard, ngram, and phonetic analyzers.
I've got the analyzers set up in elastic search, and I can begin dumping data into the index. I'm wondering if the way I'm doing it here is the best way, or if I can apply the analyzers to a single field...the reason I ask is because when I do a get /website/person/:id, I see all three fields in plain text...I was expecting to see the analyzed data here, although I guess it must only exist in an inverted index rather than on the document. Examples I've seen use multiple fields, but is it possible to add multiple analyzers to a single field?
My config.yml:
fos_elastica:
clients:
default: { host: %elastica_host%, port: %elastica_port% }
indexes:
website:
settings:
index:
analysis:
analyzer:
phonetic_analyzer:
type: "custom"
tokenizer: "lowercase"
filter: ["name_metaphone", "lowercase", "standard"]
ngram_analyzer:
type: "custom"
tokenizer: "lowercase"
filter : [ "name_ngram" ]
filter:
name_metaphone:
encoder: "metaphone"
replace: false
type: "phonetic"
name_ngram:
type: "nGram"
min_gram: 2
max_gram: 4
client: default
finder: ~
types:
person:
mappings:
name: ~
nameNGram:
analyzer: ngram_analyzer
namePhonetic:
analyzer: phonetic_analyzer
When I check the mapping it looks good:
{
"website" : {
"mappings" : {
"person" : {
"_meta" : {
"model" : "acme\\websiteBundle\\Entity\\Person"
},
"properties" : {
"name" : {
"type" : "string",
"store" : true
},
"nameNGram" : {
"type" : "string",
"store" : true,
"analyzer" : "ngram_analyzer"
},
"namePhonetic" : {
"type" : "string",
"store" : true,
"analyzer" : "phonetic_analyzer"
}
}
}
}
}
}
When I GET the document, I see that all three fields are stored in plain text... maybe i need to set STORE: FALSE for these extra fields, or, is it not being analyzed properly?
{
"_index" : "website",
"_type" : "person",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source":{
"name":"John Doe",
"namePhonetic":"John Doe",
"nameNGram":"John Doe"
}
}
EDIT: The solution I'm currently using, which still requires some refinement but tests well for most names
//Create the query object
$boolQuery = new \Elastica\Query\Bool();
//Boost exact name matches
$exactMatchQuery = new \Elastica\Query\Match();
$exactMatchQuery->setFieldParam('name', 'query', $name);
$exactMatchQuery->setFieldParam('name', 'boost', 10);
$boolQuery->addShould($exactMatchQuery);
//Create a basic Levenshtein distance query
$levenshteinMatchQuery = new \Elastica\Query\Match();
$levenshteinMatchQuery->setFieldParam('name', 'query', $name);
$levenshteinMatchQuery->setFieldParam('name', 'fuzziness', 1);
$boolQuery->addShould($levenshteinMatchQuery);
//Create a phonetic query, seeing if the name SOUNDS LIKE the name that was searched
$phoneticMatchQuery = new \Elastica\Query\Match();
$phoneticMatchQuery->setFieldParam('namePhonetic', 'query', $name);
$boolQuery->addShould($phoneticMatchQuery);
//Create an NGRAM query
$nGramMatchQuery = new \Elastica\Query\Match();
$nGramMatchQuery->setFieldParam('nameNGram', 'query', $name);
$nGramMatchQuery->setFieldParam('nameNGram', 'boost', 2);
$boolQuery->addMust($nGramMatchQuery);
return $boolQuery;
No, you can't have multiple analyzers on a single field. The way you are doing is correct way of applying multiple analyzers by having different field names for same field.
The reason you are getting namePhonetic and nameNGram also in _source field is use of
"store" : true
It tells the ElasticSearch that you need those extra fields also in response. Use
"store" : false
that will solve your problem.
If you want to see the analyzed data on a field you can use _analyze api of elasticsearch.
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-analyze.html
Yes, these fields are stored in inverted index after analysis.
I hope I have answered all your doubts. Please let me know if you need more help on this.
Thanks