ansible - Query data with json_query - json

Hello Developer Community!
I'm currently working on developing some Ansible playbooks to manage Citrix NetScaler configuration and would like to get some help about the following. I have the following data structure defined in a variable named "helpervar_get_nsvpx_nscapacity_fact":
ok: [127.0.0.1] => {
"msg": [
{
"nsadc_nscapacity": {
"actualbandwidth": "1000",
"bandwidth": "1000",
"edition": "Platinum",
"instancecount": "1",
"maxbandwidth": "100000",
"maxvcpucount": "2",
"minbandwidth": "10",
"unit": "Mbps"
},
"nsip": "10.162.237.136",
"vm_name": "NSVPX-1"
},
{
"nsadc_nscapacity": {
"actualbandwidth": "1000",
"bandwidth": "1000",
"edition": "Platinum",
"instancecount": "1",
"maxbandwidth": "100000",
"maxvcpucount": "2",
"minbandwidth": "10",
"unit": "Mbps"
},
"nsip": "10.162.237.137",
"vm_name": "NSVPX-2"
}
]
}
I have been trying to get the following expected result (I would like to get the "edition" attribute, related to a specific "nsip"):
[
"Platinum"
]
But I'm getting the following actual result:
""
I have been trying to achieve this using the following JSON query:
- debug:
msg: "{{ helpervar_get_nsvpx_nscapacity_fact | json_query(test_query) }}"
vars:
test_query: "[?(#.nsip == '10.162.237.136')].nsadc_nscapacity.edition"
I have also tried to test the above query with on-line JSON query testers and using the web-based testers, the query works, but running the query in an Ansible script shows empty result.
Could anyone help me, what could be wrong with the query?
Thank You very much in advance!

Related

How to filter Ansible's JSON output and compare with string?

I am using the yum module in ansible to list all updates on a system. The output is something like this:
results: [
{
"name": "rubygem-ffi",
"nevra": "0:rubygem-ffi-1.9.10-2.el7.x86_64",
"repo": "epel",
"epoch": "0",
"version": "1.9.10",
"release": "2.el7",
"yumstate": "available",
"arch": "x86_64"
}
{
"name": "some-package",
"nevra": "blah",
"repo": "epel",
"epoch": "0",
"version": "6",
"release": "6.el7",
"yumstate": "available",
"arch": "x86_64"
}
]
And the code I use in tasks is:
- name: yum list
yum: list=updates
register: output
What I want is to print a debug message only when the name of a package is found in the JSON output. Like this:
- debug: msg="Found it!"
when: [output.I don't know the right filter] == "rubygem-ffi"
I tried something like output.results.name or output.results|map(attribute='name')|list but they don't seem to work
Any clues?
There may be other solutions. This one works for me:
- debug: msg='Found It!'
when: item.name == 'rubygem-ffi'
with_items: output.results

How to index multidimensional arrays in couchdb

I have a multidimensional array that I want to index with CouchDB (really using Cloudant). I have users which have a list of the teams that they belong to. I want to search to find every member of that team. So, get me all the User objects that have a team object with id 79d25d41d991890350af672e0b76faed. I tried to make a json index on "Teams.id", but it didn't work because it isn't a straight array but a multidimensional array.
User
{
"_id": "683be6c086381d3edc8905dc9e948da8",
"_rev": "238-963e54ab838935f82f54e834f501dd99",
"type": "Feature",
"Kind": "Profile",
"Email": "gc#gmail.com",
"FirstName": "George",
"LastName": "Castanza",
"Teams": [
{
"id": "79d25d41d991890350af672e0b76faed",
"name": "First Team",
"level": "123"
},
{
"id": "e500c1bf691b9cfc99f05634da80b6d1",
"name": "Second Team Name",
"level": ""
},
{
"id": "4645e8a4958421f7d843d9b34c4cd9fe",
"name": "Third Team Name",
"level": "123"
}
],
"LastTeam": "79d25d41d991890350af672e0b76faed"
}
This is a lot like my response at Cloudant Selector Query but here's the deal, applied to your question:
The easiest way to run this query is using "Cloudant Query" (or "Mango", as it's called in the forthcoming CouchDB 2.0 release) -- and not the traditional MapReduce view indexing system in CouchDB. (This blog covers the differences: https://cloudant.com/blog/mango-json-vs-text-indexes/ and this one is an overview: https://developer.ibm.com/clouddataservices/2015/11/24/cloudant-query-json-index-arrays/).
Here's what your CQ index should look like:
{
"index": {
"fields": [
{"name": "Teams.[].id", "type": "string"}
]
},
"type": "text"
}
And what the subsequent query looks like:
{
"selector": {
"Teams": {"$elemMatch": {"id": "79d25d41d991890350af672e0b76faed"}}
},
"fields": [
"_id",
"FirstName",
"LastName"
]
}
You can try it yourself in the "Query" section of the Cloudant dashboard or via curl with something like this:
curl -H "Content-Type: application/json" -X POST -d '{"selector":{"Teams":{"$elemMatch":{"id":"79d25d41d991890350af672e0b76faed"}}},"fields":["_id","FirstName","LastName"]}' https://broberg.cloudant.com/teams_test/_find
That database is world-readable, so you can see the sample documents I created in there here: https://broberg.cloudant.com/teams_test/_all_docs?include_docs=true
Dig the Seinfeld theme :D
You simply need to loop through the Teams array and emit a view entry for each of the teams.
function (doc) {
if(doc.Kind === "Profile"){
for (var i=0; i<doc.Teams.length; i++) {
var team = doc.Teams[i];
emit(team.id, [doc.FirstName, doc.LastName]);
}
}
}
You can then query for all profiles with a specific team id by keying on the team id like this
.../view?key="79d25d41d991890350af672e0b76faed"
giving
{"total_rows":7,"offset":2,"rows":[
{"id":"0d15041f43b43ae07e8faa737f00032c","key":"79d25d41d991890350af672e0b76faed","value":["Adam","Alpha"]},
{"id":"68779729be3610fd8b52b22574000ae8","key":"79d25d41d991890350af672e0b76faed","value":["Bob","Bravo"]},
{"id":"9f97f1565f03aebae9ca73e207001ee1","key":"79d25d41d991890350af672e0b76faed","value":["Chuck","Charlie"]}
]}
or you can include the actual profiles in the result by adding &include_docs=true to the query.

Deeply nested JSON documents in Apache Solr

I have a deeply nested document(pseudo structure as shown below):
[{
"id": "1",
"company_id": "1",
"company_name": "company_1",
"departments":[{
"dep1" : [{
"id" : 40,
"name" : xyz
},
{
"id" : 41,
"name" : xyr
}],
"dep2": [{
}]
}]
"employeePrograms" :[{
}]
}]
How can I index these type of documents in Apache Solr?
Documentation gives the idea of immediate child documents alone.
Unfortunatelly i'm don't have huge experience with this technology, but want to help. Here is some official documentation, that might be useful: oficial doc
more specific
If you have some uncommon issue, tell about it, maybe any error, or whatever.. I would try my best to help)
Upd1 :
Solr can only maintain a 'flat' representation of the data. What you weretrying to do is not really possible. There are a number of workarounds, such as using dynamic fields and using a solr join to link multiple data sets.
Speking about a deep nesting ? I've found such an example of work around.
If you had something like that:
"docs": [
{
"name": "Product Name",
"categories": [
{
"name": "Category 1",
"priority": 8
},
{
"name": "Category 2",
"priority": 6
}
...
]
},
You have to modify it like that to make it not deeply nested :
"docs": [
{
name: "Sample Product"
categories: [
{
priority_category: "9_Category 1",
},
{
priority_category: "5_Category 2",
}
...
]
},
So, you've done something similar, check if there are any errors anywhere

Parsing json in backbone

prodCollect.fetch({
success: function(collection){
console.log(prodCollect.models.length);
var a =prodCollect.models[1];
console.log(a.attributes);
var y=_(a.attributes).toArray();
console.log(y[0]);
}
});
In variable 'a', I'm getting a model and doing console(a.attributes), I'm getting this:
Object {[{"product_id":"2","product_name":"new product","short_description":"used for training of managers","full_description":"used for training of managers","price":"20000.00","acct_manager":"rahul raja","roles":"Manager,Manager","tags":"abc,def","skills":"abc,abc","clients":"accenture,accenture,Wipro,Google"}]: Object}
Now I am unable to access the properties like 'product_name' and 'price'. I tried converting a.attributes into an array and accessing y[0] but its undefined. 'a.attributes' is an object. So I am unable to access the properties.
I am sending this from server
[
"[{\"program_name\":\"training\",\"products\":\"new product,fdgf\",\"roles\":\"Manager,CEO,random\",\"tags\":\"abc,def\",\"skills\":\"abc,def\",\"clients\":\"accenture,wipro\"},{\"program_name\":\"New progs\",\"products\":\"fdgf,ILead\",\"roles\":\"CEO,Manager,random\",\"tags\":\"abc,def\",\"skills\":\"abc,def\",\"clients\":\"\"}]",
"[{\"product_id\":\"2\",\"product_name\":\"new product\",\"short_description\":\"used for training of managers\",\"full_description\":\"used for training of managers\",\"price\":\"20000.00\",\"acct_manager\":\"rahul raja\",\"roles\":\"Manager,Manager\",\"tags\":\"abc,def\",\"skills\":\"abc,abc\",\"clients\":\"accenture,accenture,Wipro,Google\"}]"
]
so variable 'a' contains the second array
I think that the problem came from the server, your log should be like :
{
"product_id": "2",
"product_name": "new product",
"short_description": "used for training of managers",
"full_description": "used for training of managers",
"price": "20000.00",
"acct_manager": "rahul raja",
"roles": "Manager,Manager",
"tags": "abc,def",
"skills": "abc,abc",
"clients": "accenture,accenture,Wipro,Google"
}
Here is an example that illustrate what I suspected your server doing.
So as I suspected, your problem came from the server. Your server response should be like that :
[
{
"product_id": "2",
"product_name": "new product",
...
},
{
"product_id": "2",
"product_name": "new product",
...
},
...
]

Elasticseach no results for json query

I am learning elasticsearch and following along with the tutorial. I uploaded three documents into an index. When I supply the following query:
curl 'localhost:9200/vehicles/_search?query=driver.name:Jon'
I as expected get back object two and object three. However when I try querying using json:
curl localhost:9200/vehicles/_search -d'
{
"query":{
"prefix":{
"driver.name":"Jon"
}}}'
I get no results back. I am following the tutorial very closely, so I don't understand what the issue is. Any help would be really appreciated. The uploaded objects are below.
Thank you!
id:one
'{
"color": "green",
"driver": {
"born":"1989-09-12",
"name": "Ben"
},
"make": "BMW",
"model": "Aztek",
"value": 3000.0,
"year": 2003
}'
id:two
'{
"color": "black",
"driver": {
"born":"1934-09-08",
"name": "Jon"
},
"make": "Mercedes",
"model": "Benz",
"value": 10000.0,
"year": 2012
}'
id:three
'{
"color": "green",
"driver": {
"born":"1934-09-08",
"name": "Jon"
},
"make": "BMW",
"model": "Benz",
"value": 10000.0,
"year": 2012
}'
The prefix-query "matches documents that have fields containing terms with a specified prefix (not analyzed)".
Note the "not analyzed"-part. Lucene is looking for anything starting with "Jon" in the index, but the standard analyzer lowercases terms. That is, "jon" is in the index, but "Jon" is not.
Thus, if you lowercase the text in your prefix-query, it should work. Here is a runnable example: https://www.found.no/play/gist/7629456
Try:
curl -XGET "http://localhost:9200/vehicles/_search" -d '
{
"query": {"query_string" : { "query" : "driver.name:Jon" }}
}'
In any case, If you are new to elasticsearch I really recommend you read the documentation because there are lots of types of queries. Besides, the results of queries also depends on how you index the documents, how you define the mapping, etc.
In order to use the prefix query, you need to hit a non-analyzed field. In your mappings for driver.name, if you set "index" to "not_analyzed", you can use the prefix query. Otherwise, you should use a match query or something similar.