本文介绍了Google DataStore with objectify - HashMap上的复合查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将Google App Engine用于我的REST服务后端,Google dataStore用作数据存储,并将其作为访问数据存储的对象。
实体中的一个属性是

  Map< String,String> customAttrs; 

这是因为我不知道所有参数可以来自哪个客户端。我的要求是我希望能够在HashMap中对这些参数进行索引。
我看了下面的问题:



并尝试了接受的答案中提到的内容它适用于我,我能够根据customAttrs中的属性通过使用

  filter(customAttrs .key1 ,value1)

基于客户端在REST API调用中传递的任何queryparams。 / p>

然而,这个问题出现在复合查询的情况下。我不太了解它,但是从我所了解的情况来看,如果将排序或不等式筛选器与另一个筛选器结合使用,则必须在名为
datastore-indexes.xml 。所以实体中的一个字段是creationTime,当我做任何查询时会返回一个用户列表,我想用creationTime对它进行排序。



所以,让我们假设一个是Map customAttrs 中的键是 city 。现在,如果我只想过滤 city = London 的所有用户,那么对我来说工作正常。但是,如果我尝试让 city = London creationTime 排序的所有用户返回一个异常并且不起作用。只有在文件 datastore-indexes.xml 中添加以下内容时才有效:

 < / em> datastore-index kind =Userancestor =falsesource =manual> 
< property name =customAttrs.citydirection =asc/>
< property name =creationTimedirection =asc/>
< / datastore-index>

现在,这将破坏使用HashMap的目的,因为在这之前我需要知道customAttrs中的字段。

那么是否有任何方法可以执行组合查询,而无需事先知道这些字段?

编辑:



正如Sai的回答所述,没有办法执行这些类型的查询,而无需事先添加它将它添加到datastrore-indexes.xml中。



我想到了另一种方法,但我面临着不同的问题。



在这种方法中,不是将属性定义为

  Map< String,String> customAttrs; 

我已将其定义为字符串列表

 列表与LT;字符串> customAttrs; 

这里存储的字符串形式为key:value。例如,实体列表可能是city:abc,country:xyz,name:123



在这种情况下,我只需要在我的 datastore-indexes.xml 中定义以下内容:

 < ; datastore-index kind =Userancestor =falsesource =manual> 
< property name =customAttrsdirection =asc/>
< property name =creationTimedirection =asc/>
< / datastore-index>

对我来说这很好,因为我没有硬编码/预定义属性,可能。我可以使用

 过滤器(customAttrs,city)通过 city = abc  :abc)

使用这种方法,我可以过滤任何一个参数,结果由creationTime。



但这种方法的问题是,我只能做一种类型的自定义过滤器。
这意味着如果我想过滤城市是abc和国家是xyz(如果我使用Map方法,这是有效的),我无法做到这一点。有没有办法做到这一点。
所以基本上我的查询是,如果一个实体有一个属性是List,是否有一种方法来过滤所有那些在列表中具有字符串str1和str2的实体?

解决方案

对于您关于数组属性过滤的最新问题 -



AND 查询数组类型以查看它是否包含两个或更多元素。 GQL想要 - $ / $>

  SELECT * FROM MyEntity WHERE ArrayProperty ='value1'AND ArrayProperty ='value2'


I am using Google App Engine for my REST service backend and Google dataStore as the DB and objectify for accessing datastore.One of the properties in my entity is

Map<String,String> customAttrs;

This is because I don't know before hand what all parameters can come from the client. My requirement is that I want to be able to index on these parameters in the HashMap.I looked at the following question:

GAE w/ Objectify - Can you query a HashMap?

and tried out what was mentioned in the accepted answer and it works for me, I am able to index based on the attributes in customAttrs by using

filter("customAttrs .key1", "value1")

based on whatever queryparams are passed by the client in the REST API call.

However, the problem comes in case of composite queries. I don't know much about it but from what I understand, if you combine a sorting or an inequality filter with another filter, you have to define the combination in a file calleddatastore-indexes.xml . So one of fields in the entity is creationTime, and when I do any query which returns me a list of users, I want to sort it by creationTime.

So let's say one the keys in the Map customAttrs is city. Now if I just want to filter all users where say city=London, it works fine for me. However, if I try to get all users where city=London sorted by creationTime, it returns an exception and does not work. It works only if I add the following in the file datastore-indexes.xml:

<datastore-index kind="User" ancestor="false" source="manual">
        <property name="customAttrs.city" direction="asc" />
        <property name="creationTime" direction="asc" />
    </datastore-index>

Now this would defeat the purpose of using HashMap since here I need to know the fields inside customAttrs before hand.

So is there any way of performing composite queries without having to know the fields before hand?

EDIT:

As mentioned in the answer by Sai, that there is no way to perform these type of queries, without adding it before-hand and adding it in datastrore-indexes.xml.

I thought of another approach, but I am facing different issue there.

In this approach, instead of defining the property as

Map<String,String> customAttrs;

I have defined it as a list of strings

List<String> customAttrs;

Here the strings which are stored are of the form "key:value". For example, the list for an entity might be "city:abc","country:xyz","name:123"

In this case, I just need to define the following in my datastore-indexes.xml:

<datastore-index kind="User" ancestor="false" source="manual">
        <property name="customAttrs" direction="asc" />
        <property name="creationTime" direction="asc" />
    </datastore-index>

which is fine for me, since I am nowhere hard-coding/pre-defining what the attributes, could be. I am able to filter by city=abc by using

filter("customAttrs","city:abc")

With this approach I can filter by any one of the parameters as well as sort the results by creationTime.

But the problem with this approach is that I am able to do only one type of custom filter.Meaning if I want to filter where city is abc and country is xyz( this works if I use the Map approach), I am not able to do it. Is there any way to do it.So basically my query is that if an entity has a property which is List, is there a way to filter all those entities which have the strings "str1" AND "str2" in the List?

解决方案

For your latest question on filtering over Array properties -

It is possible to do an AND query on an Array type to see if it contains two or more elements. The GQL would like -

SELECT * FROM MyEntity WHERE ArrayProperty='value1' AND ArrayProperty='value2'

这篇关于Google DataStore with objectify - HashMap上的复合查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-23 22:21