ElasticSearch:查询一个对象数组的字段

时间:2015-09-02 16:39:32

标签: c# json elasticsearch

我使用ElasticSearch索引数据,但我在查询特定字段时遇到问题。 JSON的片段如下:

 {
 "_index": "indexName",
 "_type": "type",
 "_id": "00001",
 "color": "red",
 "place": "london",
 "person": [
      {
           "name": "john",
           "friends": [
               "mary",
               "jane"
           ]
      }
      {
           "name": "jack",
           "friends": [
               "lisa",
               "alex"
           ]
      }

 ]
 }

我需要查询索引并挑选name里面person之一为“john”的所有记录。

我正在使用Client.Search来执行此操作,并且使用以下方法查询未嵌套的字段(如color)时遇到了问题:

 var searchResults = client.Search<People>(s => s
            .Index("indexName")
            .Type("type")
            .Query(q => q
                .Bool(b => b
                    .Must(
                        x => x.Match(m => m.OnField(p => p.color).Query("red")),
                        x => x.Match(m => m.OnField(p => p.place).Query("london"))))));

我的People定义如下:

public class People
{
    public string color {get; set; }
    public string place {get; set; }
    public List<Person> person {get; set; }
}
public class Person
{
    public string name {get; set; }
    // "friends" isn't here as I don't pull data from it
}

我不确定如何查询name,因为它是“内部”people - 非常感谢任何帮助。

2 个答案:

答案 0 :(得分:4)

您需要在nested_query中包装查询以访问嵌套字段。

{
    "nested" : {
        "path" : "person",
        "query" : {
             "match" : {"person.name" : "john"}
        }
    }
}

来自documentation

的例外情况
  

对嵌套对象/文档执行查询,就像它们一样   被索引为单独的文档(它们是内部的)并导致   根父文档(或父嵌套映射)。

基本上,内部嵌套的字段作为单独的文档存储在附近(因此它们可以快速获取)原始文档。默认情况下,弹性不会加载它们,因此您需要明确告诉他您要访问它。你可以说嵌套字段是懒惰的;)

抱歉,自从我在.Net和Linq工作以来已经有很长一段时间了。不知道API。但你需要创造类似的东西。

修改 从github source和你的代码我认为你需要:

var s = new SearchDescriptor<People>()
                .Query(ff=>ff
                    .Nested(n=>n
                        .Path(f=>f.person[0])
                        .Query(q=>q.Term(f=>f.person[0].name,"john"))
                    )
                );

<强> EDIT2 你有没有尝试直接卷曲到服务器?或者在头插件中尝试查询?类似的东西:

curl -XPOST 'http://localhost:9202/indexName' -d '
{
  "query": {
    "nested": {
      "path": "person",
      "query": {
        "query_string": {
          "query": "person.name: john"
        }
      }
    }
  }
}'

这适用于我的群集(更改了列名)。

答案 1 :(得分:3)

很长一段时间后,我终于发现我的数据实际上并没有被嵌入到第一位,因此只需添加

@RestController
@RequestMapping(value="/employee")
public class HelloController {

@RequestMapping(method=RequestMethod.GET , produces="application/json",value="/hello.json")
public List<Employee> getEmployeeJson(){

    Employee emp = new Employee();
    emp.setId(1);
    emp.setName("x");

    Employee emp1 = new Employee();
    emp1.setId(2);
    emp1.setName("y");

    List<Employee> res = new ArrayList<Employee>();
    res.add(emp);
    res.add(emp1);

    return res;
}

@RequestMapping(method=RequestMethod.GET , produces="application/xml",value="/hello.xml")
public List<Employee> getEmployeeXml(){

    Employee emp = new Employee();
    emp.setId(1);
    emp.setName("x");

    Employee emp1 = new Employee();
    emp1.setId(2);
    emp1.setName("y");

    List<Employee> res = new ArrayList<Employee>();
    res.add(emp);
    res.add(emp1);

    return res;
}

}

我的查询工作得很好。